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
28namespace android {
29
30class Functor;
31struct Res_png_9patch;
32
33namespace uirenderer {
34
35class RenderNode;
36class Layer;
37class Matrix4;
38class SkiaColorFilter;
39class Patch;
40
41enum 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 */
55class ANDROID_API Renderer {
56public:
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     */
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
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
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
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
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