4.2.Android hardware acceleration supplement

After uploading specific source code analysis, particularly since many things involved

 

reference

https://hencoder.com/ui-1-8/

https://blog.csdn.net/OneDeveloper/article/details/79791302

https://www.jianshu.com/p/f1feafffc365

 

concept

Before the official start need to explain, as the last part of a drawing, this issue just for the integrity of the content to be a supplement, because the content of the previous several years are involved in hardware-accelerated technical points, but some readers because they do not Learn about hardware acceleration had some doubts. So just from the difficulty in terms of this issue of content is not difficult, and most of this issue you can find these two pages:

https://developer.android.google.cn/guide/topics/graphics/hardware-accel.html

 

https://www.youtube.com/watch?v=v9S5EO7CLjo

 

Following entered.

The so-called hardware acceleration, referring to some of the computing work to specialized hardware to do, rather than ordinary calculations as to the CPU to handle. This will not only reduce the pressure on the CPU, but also thanks to handle "hand" of this work is the calculation speed is accelerated. This is the "hardware acceleration."

For Android, the hardware acceleration has its own meaning: In Android, the hardware acceleration specifically refers to the View in rendering calculations to the GPU to handle.

Further more explicit about this " draw computational work " refers to those Canvas.drawXXX drawing method () becomes the actual pixel it.

principle

In the hardware acceleration when closed, Canvas drawing work is: the content to be written into a draw Bitmap, and then after the rendering process, the pixel content of this Bitmap is used to render directly to the screen. The main computational work to draw this approach is that the drawing process operation is converted to a pixel (for example a Canvas.drawCircle () to get a specific circle of pixel information), the calculation process is accomplished by the CPU. Roughly like this:

 

And when hardware acceleration is turned on, Canvas works changed: it simply converts the contents drawn preserved for the operation of the GPU, then give it to GPU, finally to do the actual work is displayed by the GPU. Roughly like this:

As shown, when hardware acceleration is turned on, CPU do the work just to convert the drawing to operate the GPU, the workload is relatively very small.

 

How to "accelerate" the?

As can be seen from the above figures, the hardware acceleration open, drawn by the CPU calculations transferred to the GPU. But this is how you can play the "Accelerated" role, so that it becomes faster draw?

Hardware acceleration allows faster rendering, for three main reasons:

  1. Originally from the CPU to do their own thing, apportioned to the GPU part of the natural increase efficiency;
  2. With respect to the CPU is, the GPU itself already designed for the calculation of many common types of content (e.g., a simple circle, simple square) has advantages;
  3. Since the drawing process of different hardware accelerated rendering process occurs when redrawing the screen content can be optimized to avoid some duplicate operations, thus greatly enhancing rendering efficiency.

The first two of which can be summarized as one: use the GPU, rendering is fast. The reason is very intuitive, I say no more.

 

On the third point, it's the principle I generally talk about:

  • When hardware acceleration off, the drawing contents are converted into the actual pixel CPU, and then directly to the screen rendering. In particular, the "actual pixel", it is made to carry the Bitmap (hardware acceleration when closed, Canvas drawing work is: the content to be written into a draw Bitmap, and then after the rendering process this pixel content Bitmap is used to render directly to the screen). When a View interface because the content changes and calls invalidate () method, if there is no hardware acceleration is turned on, then in order to correctly calculate the Bitmap pixels, the View Father View, father View Father View and even all the way up until the top View, as well as all brothers and it intersects View, need to be invoked invalidate () to redraw. View of a change in the interface even make half of the entire screen are redrawn again, this workload is very large.

 

  • Stored in hardware acceleration turned on, the contents of the drawing will be converted to the GPU down operation (referred to as a carrier in the form of display list, also called the DisplayList corresponding class), then transferred to the GPU. Since all the drawing contents do not become the final pixel , so it is independent among them, then when the contents of the interface changes, as long as changed the View calls invalidate () method to update its corresponding GPU operating like, as its parent and sibling View View, just as it is. Then the workload on the small.

 

It is for the above reasons, the hardware acceleration is not only due to the introduction of GPU rendering to improve efficiency, but also due to changes in the drawing mechanism, and greatly improved the efficiency of the interface refresh content changes.

 

Here is a point to note, with or without hardware acceleration, while drawing UI on the screen, or the need to re-draw the entire contents of the screen, rather than just part of the drawing content changes, the reason for the acceleration, is because of the Display List the cached related operations, rather than repeat the operation each time to go up.

 

Therefore, the above three compression summarize, there are two hardware-accelerated faster reasons:

  • With the GPU, the faster the drawing;
  • Drawing change mechanism, resulting in greatly improved efficiency refresh the screen when content changes.

layer type

In the period of a few years before the content I mentioned a few times, if you are drawing operation does not support hardware acceleration, you need to manually turn off hardware acceleration to draw the interface, shut down it is through this line of code:

view.setLayerType(LAYER_TYPE_SOFTWARE, null);

 

Hardware acceleration can be used setLayerType () to turn off hardware acceleration, but in fact this method is used to set the View Layer:

  1. When the parameter is LAYER_TYPE_SOFTWARE, using software to draw View Layer, to draw a Bitmap, and way off hardware acceleration;
  2. When the parameter is LAYER_TYPE_HARDWARE, using a GPU draw View Layer, to draw a OpenGL texture (if the hardware acceleration off, and then VIEW_TYPE_SOFTWARE consistent behavior);
  3. Parameter is LAYER_TYPE_NONE, close the View Layer.

 

View Layer can accelerate the refresh efficiency without invalidate (), but you need to call invalidate () refresh can not be accelerated.

View Layer draw the actual time consumed is higher than when not using the View Layer, so be careful to use.

 

Many people have had questions: What is the layer type? If this method is hardware acceleration switch, then it's not an argument why the LAYER_TYPE_SOFTWARE to turn off hardware acceleration and a LAYER_TYPE_HARDWARE to open the hardware acceleration so two parameters, but three parameters, as well as a LAYER_TYPE_NONE outside SOFTWARE and HARDWARE? Is software can neither draw, do not have the hardware to draw it?

In fact, it had the role of this method is not used to the switch hardware acceleration, just when its argument is LAYER_TYPE_SOFTWARE to be " the way " to turn off hardware acceleration only; and in addition to this method, Android does not provide special the View-level hardware acceleration switch, so it is "the way" approach became a switch hardware acceleration.

 

View Layer View Layer is, hardware acceleration hardware acceleration, both the two concepts, but there existed a place to cross.

The so-called View Layer, also known as off-screen buffer (Off-screen Buffer), its role is to enable an individual to draw this place View, instead of using the Bitmap drawing software or hardware-accelerated GPU. This "place" may be a separate Bitmap, it may be an OpenGL texture (texture, OpenGL texture image can be simply understood as meaning), depending on hardware acceleration is turned on.

 

After using setLayerType () method what good is it, that is in the set View Layer, you can (if there is no hardware to open acceleration based on the original, is based on does not turn on; If you turn hardware acceleration, then opened the basis on), further improvement will redraw efficiency View.

 

The use of what to draw View is not the key, the key is when setting View Layer time (non-NONE), it's drawing will be cached, is to use the Off-screen buffers, and the cache is final draw result is not like hardware as just saved GPU acceleration operation down again to the GPU to calculate, because the hardware acceleration turned on, the content needs to be drawn will be converted to store GPU down operation, the form of the carrier is referred to as display list, also called the corresponding class DisplayList, then transferred to the GPU, but all the drawing contents have not become final pixels, so every time you draw, or the need to convert the DisplayList saved for the final content of pixels.

By way of further cache, redraw further improve the efficiency of View: As long as the content of the drawing has not changed, then the CPU either draw (software-based rendering model) or to draw GPU (hardware acceleration model), they do not have to be recalculated, and as long as the cache before use with a draw result on it.

 

Based on this principle, during the move, rotate, etc. (without calling invalidate ()) of the property animation when open Hardware Layer will greatly enhance the efficiency of animation, because there is no change in the animation process View itself, but its position or angle changes, and this change is complete, and does not need to redraw the entire View through simple calculation by the GPU. So open the Hardware Layer In this animation process, it can make the already rely on hardware acceleration and become fluent animations become more fluid. Implementation something like this:

view.setLayerType(LAYER_TYPE_HARDWARE, null);  
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);

animator.addListener(new AnimatorListenerAdapter() {  
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(LAYER_TYPE_NONE, null);
    }
});

animator.start();  

 

Or if you are using ViewPropertyAnimator, then more simple:

view.animate ()   
        .rotationY ( 90 ) 
        .withLayer (); // withLayer () can automate complicated operation code above

 

However, we must note that only you are to translationX translationY rotation alpha, etc. without calling invalidate () attributes do animation time , this method is only applicable because this method itself is to use the interface does not occur when the cache is not updated savings brought about by time.

So simply put - this way, does not apply to custom property-based animation rendering . You must remember this sentence.

 

In addition, because after setting View Layer, View when drawing each time the initial and invalidate (after) redraw, needs to be drawn to work twice (once to draw Layer, Layer to display a draw from), so in fact it the efficiency of each drawing is lowered . So be sure to carefully use the View Layer, go to use when you need to use it.

 

Further, in addition to hardware acceleration for closing and two auxiliary property animation functions, Layer View can also be used to increase the number of rendering effects, such as setting a View becomes ColorMatrixColorFilter to make black and white:

ColorMatrix colorMatrix = new ColorMatrix();  
colorMatrix.setSaturation(0);
Paint paint = new Paint();  
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));

view.setLayerType(LAYER_TYPE_HARDWARE, paint);  

  

The relationship between the opening and window hardware acceleration layer type of

  • ? ? canvas.savelayer whether or not to open the hardware acceleration, layer type set up how, you can create a bitmap, namely off-screen buffer.

 

  • If the window does not open hardware acceleration,

LAYER_TYPE_NONE, it would not create a drawing cache, regardless of whether or invalidate, the view will be drawing code execution from start to finish again.

LAYER_TYPE_HARDWARE, and LAYER_TYPE_SOFTWARE same.

LAYER_TYPE_SOFTWARE, creates a drawing cache (buildDrawingCache), the drawing operation to draw the bitmap,

 

  • If the window open hardware acceleration

LAYER_TYPE_NONE, it would not create the hardware layer, that is, hardware-accelerated rendering process

LAYER_TYPE_HARDWARE, will draw to a hardware layer, similar to the bitmap, so long as the addition does not call invalidate those properties, and other properties will be redrawn after the modification.

LAYER_TYPE_SOFTWARE, creates a drawing cache (buildDrawingCache), the drawing operation to draw the bitmap

 

public  void setLayerType ( int layerType, @Nullable the Paint Paint) {
     IF (layerType <LAYER_TYPE_NONE || layerType> LAYER_TYPE_HARDWARE) {
         the throw  new new an IllegalArgumentException ( "Layer One type of CAN BE only: LAYER_TYPE_NONE," 
                + "or LAYER_TYPE_HARDWARE LAYER_TYPE_SOFTWARE" ); 
    } 

    // tell the underlying hardware layer is turned on, if turned on, it is carried out after the draw on this hardware layer. 
    Boolean typeChanged = mRenderNode.setLayerType (layerType); 

    IF (! typeChanged) { 
        setLayerPaint (Paint); 
        return ; 
    } 

    IF (layerType =! LAYER_TYPE_SOFTWARE) {
        // Destroy any previous software drawing cache if present
        // NOTE: even if previous layer type is HW, we do this to ensure we've cleaned up
        // drawing cache created in View#draw when drawing to a SW canvas.
        destroyDrawingCache();
    }

    mLayerType = layerType;
    mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : paint;
    mRenderNode.setLayerPaint(mLayerPaint);

    // draw() behaves differently if we are on a layer, so we need to
    // invalidate() here
    invalidateParentCaches();
    invalidate(true);
}

  

Caution

All cache is concerned, there is a possibility of failure of the cache. If at any time during the animation call view.invalidate (), then layer it is necessary to re-render. Often abandoned hardware layers will be worse than the absence of layers of situation, because, as mentioned above, the hardware layers will involve additional expenses when setting cache. If you frequently need to re-buffer layer, then there will be great damage.

This issue is also very vulnerable, because often there are some more animated movement. If now there is a three part mobile animation:

The ViewGroup the Parent 

- -> Child View1 (moves to the left) 

- -> Child View2 (moving to the right) 

- -> Child View3 (upward movement)

 

If you just set up a layer on the parent layout ViewGroup, it will often cache invalidation, because ViewGroup will continue to change as the child View. However, for each individual sub-Views, they just shift. In this case, preferably provided for each sub-View Hardware Layer (rather than on the parent layout).

Again, usually a plurality of sub-View on the appropriate settings Hardware Layer, so they do not fail at run-time animation.

 

Several layer type performance

  1. If you just simply do animation, not dynamically modify content View, then the performance as: Hardware Layer> = Software Layer> Normal Layer
  2. If you do animation while dynamically modify content View, then the performance is: Normal Layer> Software Layer = Hardware Layer
  3. Hardware Layer animation does have greatly improved performance, but if you use good, then might as well do
  4. If you do find that by Systrace animation when each frame in buildDrawingCache / SW (main thread) or buildLayer (rendering thread), please see the logic of your code
  5. In some cases due to the system, such as the picture is larger than the Cache, invalidate logic problems, you can contact mobile phone manufacturers to modify together

 

problem

LAYER_TYPE_SOFTWARE, if called setAlpah / setTranslationX and other methods will be used drawing cache, or will redraw?

Although the traverse from top to bottom, but did not make any redrawing or reconstruction displaylist.

 

After the hardware acceleration is turned on, calls setAlpah / setTranslationX other methods to make the parent view to redraw it?

will not

 

 

 

Guess you like

Origin www.cnblogs.com/muouren/p/11706408.html