1 /*
2  * Copyright (C) 2013 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_RENDERER_H
18 #define ANDROID_HWUI_RENDERER_H
19 
20 #include <SkColorFilter.h>
21 #include <SkPaint.h>
22 #include <SkRegion.h>
23 
24 #include <utils/String8.h>
25 
26 #include "AssetAtlas.h"
27 
28 namespace android {
29 
30 class Functor;
31 struct Res_png_9patch;
32 
33 namespace uirenderer {
34 
35 class RenderNode;
36 class Layer;
37 class Matrix4;
38 class SkiaColorFilter;
39 class Patch;
40 
41 enum DrawOpMode {
42     kDrawOpMode_Immediate,
43     kDrawOpMode_Defer,
44     kDrawOpMode_Flush
45 };
46 
47 /**
48  * Hwui's abstract version of Canvas.
49  *
50  * Provides methods for frame state operations, as well as the SkCanvas style transform/clip state,
51  * and varied drawing operations.
52  *
53  * Should at some point interact with native SkCanvas.
54  */
55 class ANDROID_API Renderer {
56 public:
~Renderer()57     virtual ~Renderer() {}
58 
59     /**
60      * Safely retrieves the mode from the specified xfermode. If the specified
61      * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
62      */
getXfermode(SkXfermode * mode)63     static inline SkXfermode::Mode getXfermode(SkXfermode* mode) {
64         SkXfermode::Mode resultMode;
65         if (!SkXfermode::AsMode(mode, &resultMode)) {
66             resultMode = SkXfermode::kSrcOver_Mode;
67         }
68         return resultMode;
69     }
70 
71     // TODO: move to a method on android:Paint
paintWillNotDraw(const SkPaint & paint)72     static inline bool paintWillNotDraw(const SkPaint& paint) {
73         return paint.getAlpha() == 0
74                 && !paint.getColorFilter()
75                 && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
76     }
77 
78     // TODO: move to a method on android:Paint
paintWillNotDrawText(const SkPaint & paint)79     static inline bool paintWillNotDrawText(const SkPaint& paint) {
80         return paint.getAlpha() == 0
81                 && paint.getLooper() == NULL
82                 && !paint.getColorFilter()
83                 && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
84     }
85 
isBlendedColorFilter(const SkColorFilter * filter)86     static bool isBlendedColorFilter(const SkColorFilter* filter) {
87         if (filter == NULL) {
88             return false;
89         }
90         return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0;
91     }
92 
93 // ----------------------------------------------------------------------------
94 // Frame state operations
95 // ----------------------------------------------------------------------------
96     /**
97      * Sets the dimension of the underlying drawing surface. This method must
98      * be called at least once every time the drawing surface changes size.
99      *
100      * @param width The width in pixels of the underlysing surface
101      * @param height The height in pixels of the underlysing surface
102      */
103     virtual void setViewport(int width, int height) = 0;
104 
105     /**
106      * Prepares the renderer to draw a frame. This method must be invoked
107      * at the beginning of each frame. When this method is invoked, the
108      * entire drawing surface is assumed to be redrawn.
109      *
110      * @param opaque If true, the target surface is considered opaque
111      *               and will not be cleared. If false, the target surface
112      *               will be cleared
113      */
114     virtual status_t prepare(bool opaque) = 0;
115 
116     /**
117      * Prepares the renderer to draw a frame. This method must be invoked
118      * at the beginning of each frame. Only the specified rectangle of the
119      * frame is assumed to be dirty. A clip will automatically be set to
120      * the specified rectangle.
121      *
122      * @param left The left coordinate of the dirty rectangle
123      * @param top The top coordinate of the dirty rectangle
124      * @param right The right coordinate of the dirty rectangle
125      * @param bottom The bottom coordinate of the dirty rectangle
126      * @param opaque If true, the target surface is considered opaque
127      *               and will not be cleared. If false, the target surface
128      *               will be cleared in the specified dirty rectangle
129      */
130     virtual status_t prepareDirty(float left, float top, float right, float bottom,
131             bool opaque) = 0;
132 
133     /**
134      * Indicates the end of a frame. This method must be invoked whenever
135      * the caller is done rendering a frame.
136      */
137     virtual void finish() = 0;
138 
139 // ----------------------------------------------------------------------------
140 // Canvas state operations
141 // ----------------------------------------------------------------------------
142     // Save (layer)
143     virtual int getSaveCount() const = 0;
144     virtual int save(int flags) = 0;
145     virtual void restore() = 0;
146     virtual void restoreToCount(int saveCount) = 0;
147 
148     virtual int saveLayer(float left, float top, float right, float bottom,
149             const SkPaint* paint, int flags) = 0;
150 
saveLayerAlpha(float left,float top,float right,float bottom,int alpha,int flags)151     int saveLayerAlpha(float left, float top, float right, float bottom,
152             int alpha, int flags) {
153         SkPaint paint;
154         paint.setAlpha(alpha);
155         return saveLayer(left, top, right, bottom, &paint, flags);
156     }
157 
158     // Matrix
159     virtual void getMatrix(SkMatrix* outMatrix) const = 0;
160     virtual void translate(float dx, float dy, float dz = 0.0f) = 0;
161     virtual void rotate(float degrees) = 0;
162     virtual void scale(float sx, float sy) = 0;
163     virtual void skew(float sx, float sy) = 0;
164 
165     virtual void setMatrix(const SkMatrix& matrix) = 0;
166     virtual void concatMatrix(const SkMatrix& matrix) = 0;
167 
168     // clip
169     virtual const Rect& getLocalClipBounds() const = 0;
170     virtual bool quickRejectConservative(float left, float top,
171             float right, float bottom) const = 0;
172     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) = 0;
173     virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
174     virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
175 
176     // Misc - should be implemented with SkPaint inspection
177     virtual void resetPaintFilter() = 0;
178     virtual void setupPaintFilter(int clearBits, int setBits) = 0;
179 
180 // ----------------------------------------------------------------------------
181 // Canvas draw operations
182 // ----------------------------------------------------------------------------
183     virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0;
184 
185     // Bitmap-based
186     virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0;
187     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
188             float srcRight, float srcBottom, float dstLeft, float dstTop,
189             float dstRight, float dstBottom, const SkPaint* paint) = 0;
190     virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0;
191     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
192             const float* vertices, const int* colors, const SkPaint* paint) = 0;
193     virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
194             float left, float top, float right, float bottom, const SkPaint* paint) = 0;
195 
196     // Shapes
197     virtual status_t drawRect(float left, float top, float right, float bottom,
198             const SkPaint* paint) = 0;
199     virtual status_t drawRects(const float* rects, int count, const SkPaint* paint) = 0;
200     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
201             float rx, float ry, const SkPaint* paint) = 0;
202     virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint) = 0;
203     virtual status_t drawOval(float left, float top, float right, float bottom,
204             const SkPaint* paint) = 0;
205     virtual status_t drawArc(float left, float top, float right, float bottom,
206             float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) = 0;
207     virtual status_t drawPath(const SkPath* path, const SkPaint* paint) = 0;
208     virtual status_t drawLines(const float* points, int count, const SkPaint* paint) = 0;
209     virtual status_t drawPoints(const float* points, int count, const SkPaint* paint) = 0;
210 
211     // Text
212     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
213             const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
214             DrawOpMode drawOpMode = kDrawOpMode_Immediate) = 0;
215     virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
216             float hOffset, float vOffset, const SkPaint* paint) = 0;
217     virtual status_t drawPosText(const char* text, int bytesCount, int count,
218             const float* positions, const SkPaint* paint) = 0;
219 
220 // ----------------------------------------------------------------------------
221 // Canvas draw operations - special
222 // ----------------------------------------------------------------------------
223     virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty,
224             int32_t replayFlags) = 0;
225 
226     // TODO: rename for consistency
227     virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty) = 0;
228 }; // class Renderer
229 
230 }; // namespace uirenderer
231 }; // namespace android
232 
233 #endif // ANDROID_HWUI_RENDERER_H
234