OpenGLRenderer.h revision 9d865512f1a39bac6bed612b24023213d5a1fb1d
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
45namespace android {
46namespace uirenderer {
47
48///////////////////////////////////////////////////////////////////////////////
49// Renderer
50///////////////////////////////////////////////////////////////////////////////
51
52class 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 */
58class OpenGLRenderer {
59public:
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
135protected:
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
188private:
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