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