Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_HWUI_OPENGL_RENDERER_H
     18 #define ANDROID_HWUI_OPENGL_RENDERER_H
     19 
     20 #include <GLES2/gl2.h>
     21 #include <GLES2/gl2ext.h>
     22 
     23 #include <SkBitmap.h>
     24 #include <SkMatrix.h>
     25 #include <SkPaint.h>
     26 #include <SkRegion.h>
     27 #include <SkShader.h>
     28 #include <SkXfermode.h>
     29 
     30 #include <utils/Functor.h>
     31 #include <utils/RefBase.h>
     32 #include <utils/Vector.h>
     33 
     34 #include "Debug.h"
     35 #include "Extensions.h"
     36 #include "Matrix.h"
     37 #include "Program.h"
     38 #include "Rect.h"
     39 #include "Snapshot.h"
     40 #include "Vertex.h"
     41 #include "SkiaShader.h"
     42 #include "SkiaColorFilter.h"
     43 #include "Caches.h"
     44 
     45 namespace android {
     46 namespace uirenderer {
     47 
     48 ///////////////////////////////////////////////////////////////////////////////
     49 // Renderer
     50 ///////////////////////////////////////////////////////////////////////////////
     51 
     52 class DisplayList;
     53 
     54 /**
     55  * OpenGL renderer used to draw accelerated 2D graphics. The API is a
     56  * simplified version of Skia's Canvas API.
     57  */
     58 class OpenGLRenderer {
     59 public:
     60     OpenGLRenderer();
     61     virtual ~OpenGLRenderer();
     62 
     63     virtual void setViewport(int width, int height);
     64 
     65     void prepare(bool opaque);
     66     virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
     67     virtual void finish();
     68 
     69     // These two calls must not be recorded in display lists
     70     virtual void interrupt();
     71     virtual void resume();
     72 
     73     virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
     74 
     75     int getSaveCount() const;
     76     virtual int save(int flags);
     77     virtual void restore();
     78     virtual void restoreToCount(int saveCount);
     79 
     80     virtual int saveLayer(float left, float top, float right, float bottom,
     81             SkPaint* p, int flags);
     82     virtual int saveLayerAlpha(float left, float top, float right, float bottom,
     83             int alpha, int flags);
     84 
     85     virtual void translate(float dx, float dy);
     86     virtual void rotate(float degrees);
     87     virtual void scale(float sx, float sy);
     88     virtual void skew(float sx, float sy);
     89 
     90     void getMatrix(SkMatrix* matrix);
     91     virtual void setMatrix(SkMatrix* matrix);
     92     virtual void concatMatrix(SkMatrix* matrix);
     93 
     94     const Rect& getClipBounds();
     95     bool quickReject(float left, float top, float right, float bottom);
     96     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
     97 
     98     virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
     99             Rect& dirty, uint32_t level = 0);
    100     virtual void outputDisplayList(DisplayList* displayList, uint32_t level = 0);
    101     virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
    102     virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
    103     virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
    104     virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
    105             float srcRight, float srcBottom, float dstLeft, float dstTop,
    106             float dstRight, float dstBottom, SkPaint* paint);
    107     virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
    108             float* vertices, int* colors, SkPaint* paint);
    109     virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
    110             const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
    111             float left, float top, float right, float bottom, SkPaint* paint);
    112     virtual void drawColor(int color, SkXfermode::Mode mode);
    113     virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
    114     virtual void drawRoundRect(float left, float top, float right, float bottom,
    115             float rx, float ry, SkPaint* paint);
    116     virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
    117     virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
    118     virtual void drawArc(float left, float top, float right, float bottom,
    119             float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
    120     virtual void drawPath(SkPath* path, SkPaint* paint);
    121     virtual void drawLines(float* points, int count, SkPaint* paint);
    122     virtual void drawPoints(float* points, int count, SkPaint* paint);
    123     virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
    124             SkPaint* paint);
    125 
    126     virtual void resetShader();
    127     virtual void setupShader(SkiaShader* shader);
    128 
    129     virtual void resetColorFilter();
    130     virtual void setupColorFilter(SkiaColorFilter* filter);
    131 
    132     virtual void resetShadow();
    133     virtual void setupShadow(float radius, float dx, float dy, int color);
    134 
    135 protected:
    136     /**
    137      * Compose the layer defined in the current snapshot with the layer
    138      * defined by the previous snapshot.
    139      *
    140      * The current snapshot *must* be a layer (flag kFlagIsLayer set.)
    141      *
    142      * @param curent The current snapshot containing the layer to compose
    143      * @param previous The previous snapshot to compose the current layer with
    144      */
    145     virtual void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
    146 
    147     /**
    148      * Marks the specified region as dirty at the specified bounds.
    149      */
    150     void dirtyLayerUnchecked(Rect& bounds, Region* region);
    151 
    152     /**
    153      * Returns the current snapshot.
    154      */
    155     sp<Snapshot> getSnapshot() {
    156         return mSnapshot;
    157     }
    158 
    159     /**
    160      * Returns the region of the current layer.
    161      */
    162     virtual Region* getRegion() {
    163         return mSnapshot->region;
    164     }
    165 
    166     /**
    167      * Indicates whether rendering is currently targeted at a layer.
    168      */
    169     virtual bool hasLayer() {
    170         return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
    171     }
    172 
    173     /**
    174      * Returns the name of the FBO this renderer is rendering into.
    175      */
    176     virtual GLint getTargetFbo() {
    177         return 0;
    178     }
    179 
    180     /**
    181      * Renders the specified layer as a textured quad.
    182      *
    183      * @param layer The layer to render
    184      * @param rect The bounds of the layer
    185      */
    186     void drawTextureLayer(Layer* layer, const Rect& rect);
    187 
    188 private:
    189     /**
    190      * Saves the current state of the renderer as a new snapshot.
    191      * The new snapshot is saved in mSnapshot and the previous snapshot
    192      * is linked from mSnapshot->previous.
    193      *
    194      * @param flags The save flags; see SkCanvas for more information
    195      *
    196      * @return The new save count. This value can be passed to #restoreToCount()
    197      */
    198     int saveSnapshot(int flags);
    199 
    200     /**
    201      * Restores the current snapshot; mSnapshot becomes mSnapshot->previous.
    202      *
    203      * @return True if the clip was modified.
    204      */
    205     bool restoreSnapshot();
    206 
    207     /**
    208      * Sets the clipping rectangle using glScissor. The clip is defined by
    209      * the current snapshot's clipRect member.
    210      */
    211     void setScissorFromClip();
    212 
    213     /**
    214      * Creates a new layer stored in the specified snapshot.
    215      *
    216      * @param snapshot The snapshot associated with the new layer
    217      * @param left The left coordinate of the layer
    218      * @param top The top coordinate of the layer
    219      * @param right The right coordinate of the layer
    220      * @param bottom The bottom coordinate of the layer
    221      * @param alpha The translucency of the layer
    222      * @param mode The blending mode of the layer
    223      * @param flags The layer save flags
    224      * @param previousFbo The name of the current framebuffer
    225      *
    226      * @return True if the layer was successfully created, false otherwise
    227      */
    228     bool createLayer(sp<Snapshot> snapshot, float left, float top, float right, float bottom,
    229             int alpha, SkXfermode::Mode mode, int flags, GLuint previousFbo);
    230 
    231     /**
    232      * Creates a new layer stored in the specified snapshot as an FBO.
    233      *
    234      * @param layer The layer to store as an FBO
    235      * @param snapshot The snapshot associated with the new layer
    236      * @param bounds The bounds of the layer
    237      * @param previousFbo The name of the current framebuffer
    238      */
    239     bool createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> snapshot,
    240             GLuint previousFbo);
    241 
    242     /**
    243      * Compose the specified layer as a region.
    244      *
    245      * @param layer The layer to compose
    246      * @param rect The layer's bounds
    247      */
    248     void composeLayerRegion(Layer* layer, const Rect& rect);
    249 
    250     /**
    251      * Compose the specified layer as a simple rectangle.
    252      *
    253      * @param layer The layer to compose
    254      * @param rect The layer's bounds
    255      * @param swap If true, the source and destination are swapped
    256      */
    257     void composeLayerRect(Layer* layer, const Rect& rect, bool swap = false);
    258 
    259     /**
    260      * Clears all the regions corresponding to the current list of layers.
    261      * This method MUST be invoked before any drawing operation.
    262      */
    263     void clearLayerRegions();
    264 
    265     /**
    266      * Mark the layer as dirty at the specified coordinates. The coordinates
    267      * are transformed with the supplied matrix.
    268      */
    269     void dirtyLayer(const float left, const float top,
    270             const float right, const float bottom, const mat4 transform);
    271 
    272     /**
    273      * Mark the layer as dirty at the specified coordinates.
    274      */
    275     void dirtyLayer(const float left, const float top,
    276             const float right, const float bottom);
    277 
    278     /**
    279      * Draws a colored rectangle with the specified color. The specified coordinates
    280      * are transformed by the current snapshot's transform matrix.
    281      *
    282      * @param left The left coordinate of the rectangle
    283      * @param top The top coordinate of the rectangle
    284      * @param right The right coordinate of the rectangle
    285      * @param bottom The bottom coordinate of the rectangle
    286      * @param color The rectangle's ARGB color, defined as a packed 32 bits word
    287      * @param mode The Skia xfermode to use
    288      * @param ignoreTransform True if the current transform should be ignored
    289      * @param ignoreBlending True if the blending is set by the caller
    290      */
    291     void drawColorRect(float left, float top, float right, float bottom,
    292             int color, SkXfermode::Mode mode, bool ignoreTransform = false);
    293 
    294     /**
    295      * Draws the shape represented by the specified path texture.
    296      * This method invokes drawPathTexture() but takes into account
    297      * the extra left/top offset and the texture offset to correctly
    298      * position the final shape.
    299      *
    300      * @param left The left coordinate of the shape to render
    301      * @param top The top coordinate of the shape to render
    302      * @param texture The texture reprsenting the shape
    303      * @param paint The paint to draw the shape with
    304      */
    305     void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
    306 
    307     /**
    308      * Renders the rect defined by the specified bounds as a shape.
    309      * This will render the rect using a path texture, which is used to render
    310      * rects with stroke effects.
    311      *
    312      * @param left The left coordinate of the rect to draw
    313      * @param top The top coordinate of the rect to draw
    314      * @param right The right coordinate of the rect to draw
    315      * @param bottom The bottom coordinate of the rect to draw
    316      * @param p The paint to draw the rect with
    317      */
    318     void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);
    319 
    320     /**
    321      * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
    322      * different compositing rules.
    323      *
    324      * @param texture The texture to draw with
    325      * @param left The x coordinate of the bitmap
    326      * @param top The y coordinate of the bitmap
    327      * @param paint The paint to render with
    328      */
    329     void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);
    330 
    331     /**
    332      * Renders the rect defined by the specified bounds as an anti-aliased rect.
    333      *
    334      * @param left The left coordinate of the rect to draw
    335      * @param top The top coordinate of the rect to draw
    336      * @param right The right coordinate of the rect to draw
    337      * @param bottom The bottom coordinate of the rect to draw
    338      * @param color The color of the rect
    339      * @param mode The blending mode to draw the rect
    340      */
    341     void drawAARect(float left, float top, float right, float bottom,
    342             int color, SkXfermode::Mode mode);
    343 
    344     /**
    345      * Draws a textured rectangle with the specified texture. The specified coordinates
    346      * are transformed by the current snapshot's transform matrix.
    347      *
    348      * @param left The left coordinate of the rectangle
    349      * @param top The top coordinate of the rectangle
    350      * @param right The right coordinate of the rectangle
    351      * @param bottom The bottom coordinate of the rectangle
    352      * @param texture The texture name to map onto the rectangle
    353      * @param alpha An additional translucency parameter, between 0.0f and 1.0f
    354      * @param mode The blending mode
    355      * @param blend True if the texture contains an alpha channel
    356      */
    357     void drawTextureRect(float left, float top, float right, float bottom, GLuint texture,
    358             float alpha, SkXfermode::Mode mode, bool blend);
    359 
    360     /**
    361      * Draws a textured rectangle with the specified texture. The specified coordinates
    362      * are transformed by the current snapshot's transform matrix.
    363      *
    364      * @param left The left coordinate of the rectangle
    365      * @param top The top coordinate of the rectangle
    366      * @param right The right coordinate of the rectangle
    367      * @param bottom The bottom coordinate of the rectangle
    368      * @param texture The texture to use
    369      * @param paint The paint containing the alpha, blending mode, etc.
    370      */
    371     void drawTextureRect(float left, float top, float right, float bottom,
    372             Texture* texture, SkPaint* paint);
    373 
    374     /**
    375      * Draws a textured mesh with the specified texture. If the indices are omitted,
    376      * the mesh is drawn as a simple quad. The mesh pointers become offsets when a
    377      * VBO is bound.
    378      *
    379      * @param left The left coordinate of the rectangle
    380      * @param top The top coordinate of the rectangle
    381      * @param right The right coordinate of the rectangle
    382      * @param bottom The bottom coordinate of the rectangle
    383      * @param texture The texture name to map onto the rectangle
    384      * @param alpha An additional translucency parameter, between 0.0f and 1.0f
    385      * @param mode The blending mode
    386      * @param blend True if the texture contains an alpha channel
    387      * @param vertices The vertices that define the mesh
    388      * @param texCoords The texture coordinates of each vertex
    389      * @param elementsCount The number of elements in the mesh, required by indices
    390      * @param swapSrcDst Whether or not the src and dst blending operations should be swapped
    391      * @param ignoreTransform True if the current transform should be ignored
    392      * @param vbo The VBO used to draw the mesh
    393      * @param ignoreScale True if the model view matrix should not be scaled
    394      * @param dirty True if calling this method should dirty the current layer
    395      */
    396     void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
    397             float alpha, SkXfermode::Mode mode, bool blend,
    398             GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
    399             bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
    400             bool ignoreScale = false, bool dirty = true);
    401 
    402     /**
    403      * Draws text underline and strike-through if needed.
    404      *
    405      * @param text The text to decor
    406      * @param bytesCount The number of bytes in the text
    407      * @param length The length in pixels of the text, can be <= 0.0f to force a measurement
    408      * @param x The x coordinate where the text will be drawn
    409      * @param y The y coordinate where the text will be drawn
    410      * @param paint The paint to draw the text with
    411      */
    412     void drawTextDecorations(const char* text, int bytesCount, float length,
    413             float x, float y, SkPaint* paint);
    414 
    415     /**
    416      * Draws a path texture. Path textures are alpha8 bitmaps that need special
    417      * compositing to apply colors/filters/etc.
    418      *
    419      * @param texture The texture to render
    420      * @param x The x coordinate where the texture will be drawn
    421      * @param y The y coordinate where the texture will be drawn
    422      * @param paint The paint to draw the texture with
    423      */
    424     void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
    425 
    426     /**
    427      * Resets the texture coordinates stored in mMeshVertices. Setting the values
    428      * back to default is achieved by calling:
    429      *
    430      * resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
    431      *
    432      * @param u1 The left coordinate of the texture
    433      * @param v1 The bottom coordinate of the texture
    434      * @param u2 The right coordinate of the texture
    435      * @param v2 The top coordinate of the texture
    436      */
    437     void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2);
    438 
    439     /**
    440      * Gets the alpha and xfermode out of a paint object. If the paint is null
    441      * alpha will be 255 and the xfermode will be SRC_OVER.
    442      *
    443      * @param paint The paint to extract values from
    444      * @param alpha Where to store the resulting alpha
    445      * @param mode Where to store the resulting xfermode
    446      */
    447     inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
    448 
    449     /**
    450      * Binds the specified texture. The texture unit must have been selected
    451      * prior to calling this method.
    452      */
    453     inline void bindTexture(GLuint texture) {
    454         glBindTexture(GL_TEXTURE_2D, texture);
    455     }
    456 
    457     /**
    458      * Binds the specified EGLImage texture. The texture unit must have been selected
    459      * prior to calling this method.
    460      */
    461     inline void bindExternalTexture(GLuint texture) {
    462         glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
    463     }
    464 
    465     /**
    466      * Enable or disable blending as necessary. This function sets the appropriate
    467      * blend function based on the specified xfermode.
    468      */
    469     inline void chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description,
    470             bool swapSrcDst = false);
    471 
    472     /**
    473      * Safely retrieves the mode from the specified xfermode. If the specified
    474      * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
    475      */
    476     inline SkXfermode::Mode getXfermode(SkXfermode* mode);
    477 
    478     /**
    479      * Use the specified program with the current GL context. If the program is already
    480      * in use, it will not be bound again. If it is not in use, the current program is
    481      * marked unused and the specified program becomes used and becomes the new
    482      * current program.
    483      *
    484      * @param program The program to use
    485      *
    486      * @return true If the specified program was already in use, false otherwise.
    487      */
    488     inline bool useProgram(Program* program);
    489 
    490     /**
    491      * Invoked before any drawing operation. This sets required state.
    492      */
    493     void setupDraw(bool clear = true);
    494     /**
    495      * Various methods to setup OpenGL rendering.
    496      */
    497     void setupDrawWithTexture(bool isAlpha8 = false);
    498     void setupDrawWithExternalTexture();
    499     void setupDrawAALine();
    500     void setupDrawPoint(float pointSize);
    501     void setupDrawColor(int color);
    502     void setupDrawColor(int color, int alpha);
    503     void setupDrawColor(float r, float g, float b, float a);
    504     void setupDrawAlpha8Color(int color, int alpha);
    505     void setupDrawAlpha8Color(float r, float g, float b, float a);
    506     void setupDrawShader();
    507     void setupDrawColorFilter();
    508     void setupDrawBlending(SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
    509             bool swapSrcDst = false);
    510     void setupDrawBlending(bool blend = true, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
    511             bool swapSrcDst = false);
    512     void setupDrawProgram();
    513     void setupDrawDirtyRegionsDisabled();
    514     void setupDrawModelViewIdentity(bool offset = false);
    515     void setupDrawModelView(float left, float top, float right, float bottom,
    516             bool ignoreTransform = false, bool ignoreModelView = false);
    517     void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
    518             bool ignoreTransform = false);
    519     void setupDrawPointUniforms();
    520     void setupDrawColorUniforms();
    521     void setupDrawPureColorUniforms();
    522     void setupDrawShaderIdentityUniforms();
    523     void setupDrawShaderUniforms(bool ignoreTransform = false);
    524     void setupDrawColorFilterUniforms();
    525     void setupDrawSimpleMesh();
    526     void setupDrawTexture(GLuint texture);
    527     void setupDrawExternalTexture(GLuint texture);
    528     void setupDrawTextureTransform();
    529     void setupDrawTextureTransformUniforms(mat4& transform);
    530     void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
    531     void setupDrawVertices(GLvoid* vertices);
    532     void setupDrawAALine(GLvoid* vertices, GLvoid* distanceCoords, GLvoid* lengthCoords,
    533             float strokeWidth);
    534     void finishDrawTexture();
    535     void accountForClear(SkXfermode::Mode mode);
    536 
    537     void drawRegionRects(const Region& region);
    538 
    539     /**
    540      * Should be invoked every time the glScissor is modified.
    541      */
    542     inline void dirtyClip() {
    543         mDirtyClip = true;
    544     }
    545 
    546     // Dimensions of the drawing surface
    547     int mWidth, mHeight;
    548 
    549     // Matrix used for ortho projection in shaders
    550     mat4 mOrthoMatrix;
    551 
    552     // Model-view matrix used to position/size objects
    553     mat4 mModelView;
    554 
    555     // Number of saved states
    556     int mSaveCount;
    557     // Base state
    558     sp<Snapshot> mFirstSnapshot;
    559     // Current state
    560     sp<Snapshot> mSnapshot;
    561 
    562     // Shaders
    563     SkiaShader* mShader;
    564 
    565     // Color filters
    566     SkiaColorFilter* mColorFilter;
    567 
    568     // Used to draw textured quads
    569     TextureVertex mMeshVertices[4];
    570 
    571     // Drop shadow
    572     bool mHasShadow;
    573     float mShadowRadius;
    574     float mShadowDx;
    575     float mShadowDy;
    576     int mShadowColor;
    577 
    578     // Various caches
    579     Caches& mCaches;
    580 
    581     // List of rectagnles to clear after saveLayer() is invoked
    582     Vector<Rect*> mLayers;
    583 
    584     // Indentity matrix
    585     const mat4 mIdentity;
    586 
    587     // Indicates whether the clip must be restored
    588     bool mDirtyClip;
    589 
    590     // The following fields are used to setup drawing
    591     // Used to describe the shaders to generate
    592     ProgramDescription mDescription;
    593     // Color description
    594     bool mColorSet;
    595     float mColorA, mColorR, mColorG, mColorB;
    596     // Indicates that the shader should get a color
    597     bool mSetShaderColor;
    598     // Current texture unit
    599     GLuint mTextureUnit;
    600     // Track dirty regions, true by default
    601     bool mTrackDirtyRegions;
    602     // Texture coordinates slot
    603     int mTexCoordsSlot;
    604 
    605     friend class DisplayListRenderer;
    606 
    607 }; // class OpenGLRenderer
    608 
    609 }; // namespace uirenderer
    610 }; // namespace android
    611 
    612 #endif // ANDROID_HWUI_OPENGL_RENDERER_H
    613