blob: a0290e37012fe4bede6b75720d5ab3884707d82a [file] [log] [blame]
Chris Craik2af46352012-11-26 18:30:17 -08001/*
Romain Guy7031ff62013-02-22 11:48:16 -08002 * Copyright (C) 2013 The Android Open Source Project
Chris Craik2af46352012-11-26 18:30:17 -08003 *
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_DISPLAY_OPERATION_H
18#define ANDROID_HWUI_DISPLAY_OPERATION_H
19
Romain Guy7031ff62013-02-22 11:48:16 -080020#ifndef LOG_TAG
21 #define LOG_TAG "OpenGLRenderer"
22#endif
23
Chris Craik2af46352012-11-26 18:30:17 -080024#include <SkXfermode.h>
25
Chris Craik0776a602013-02-14 15:36:01 -080026#include <private/hwui/DrawGlInfo.h>
27
Chris Craik2af46352012-11-26 18:30:17 -080028#include "OpenGLRenderer.h"
Chris Craikc3566d02013-02-04 16:16:33 -080029#include "DeferredDisplayList.h"
Chris Craik2af46352012-11-26 18:30:17 -080030#include "DisplayListRenderer.h"
31#include "utils/LinearAllocator.h"
32
33#define CRASH() do { \
34 *(int *)(uintptr_t)0xbbadbeef = 0; \
35 ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
36} while(false)
37
38#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
39#define MATRIX_ARGS(m) \
40 m->get(0), m->get(1), m->get(2), \
41 m->get(3), m->get(4), m->get(5), \
42 m->get(6), m->get(7), m->get(8)
43#define RECT_STRING "%.2f %.2f %.2f %.2f"
44#define RECT_ARGS(r) \
45 r.left, r.top, r.right, r.bottom
46
47// Use OP_LOG for logging with arglist, OP_LOGS if just printing char*
48#define OP_LOGS(s) OP_LOG("%s", s)
Chris Craik3dc553b2013-02-04 12:45:13 -080049#define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ )
Chris Craik2af46352012-11-26 18:30:17 -080050
Chris Craik2af46352012-11-26 18:30:17 -080051namespace android {
52namespace uirenderer {
53
54/**
55 * Structure for storing canvas operations when they are recorded into a DisplayList, so that they
56 * may be replayed to an OpenGLRenderer.
57 *
58 * To avoid individual memory allocations, DisplayListOps may only be allocated into a
59 * LinearAllocator's managed memory buffers. Each pointer held by a DisplayListOp is either a
60 * pointer into memory also allocated in the LinearAllocator (mostly for text and float buffers) or
61 * references a externally refcounted object (Sk... and Skia... objects). ~DisplayListOp() is
62 * never called as LinearAllocators are simply discarded, so no memory management should be done in
63 * this class.
64 */
65class DisplayListOp {
66public:
67 // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted.
68 // standard new() intentionally not implemented, and delete/deconstructor should never be used.
69 virtual ~DisplayListOp() { CRASH(); }
70 static void operator delete(void* ptr) { CRASH(); }
71 /** static void* operator new(size_t size); PURPOSELY OMITTED **/
72 static void* operator new(size_t size, LinearAllocator& allocator) {
73 return allocator.alloc(size);
74 }
75
76 enum OpLogFlag {
77 kOpLogFlag_Recurse = 0x1,
78 kOpLogFlag_JSON = 0x2 // TODO: add?
79 };
80
Chet Haasedd671592013-04-19 14:54:34 -070081 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
82 bool useQuickReject) = 0;
Chris Craikc3566d02013-02-04 16:16:33 -080083
Chet Haasedd671592013-04-19 14:54:34 -070084 virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
85 bool useQuickReject) = 0;
Chris Craikff785832013-03-08 13:12:16 -080086
87 virtual void output(int level, uint32_t logFlags = 0) = 0;
Chris Craik2af46352012-11-26 18:30:17 -080088
89 // NOTE: it would be nice to declare constants and overriding the implementation in each op to
90 // point at the constants, but that seems to require a .cpp file
91 virtual const char* name() = 0;
Chris Craikff785832013-03-08 13:12:16 -080092
93 /**
94 * Stores the relevant canvas state of the object between deferral and replay (if the canvas
95 * state supports being stored) See OpenGLRenderer::simpleClipAndState()
96 *
97 * TODO: don't reserve space for StateOps that won't be deferred
98 */
99 DeferredDisplayState state;
100
Chris Craik2af46352012-11-26 18:30:17 -0800101};
102
103class StateOp : public DisplayListOp {
104public:
105 StateOp() {};
106
107 virtual ~StateOp() {}
108
Chet Haasedd671592013-04-19 14:54:34 -0700109 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
110 bool useQuickReject) {
Chris Craikff785832013-03-08 13:12:16 -0800111 // default behavior only affects immediate, deferrable state, issue directly to renderer
112 applyState(deferStruct.mRenderer, saveCount);
113 }
114
Chris Craikc3566d02013-02-04 16:16:33 -0800115 /**
116 * State operations are applied directly to the renderer, but can cause the deferred drawing op
117 * list to flush
118 */
Chet Haasedd671592013-04-19 14:54:34 -0700119 virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
120 bool useQuickReject) {
Chris Craikff785832013-03-08 13:12:16 -0800121 applyState(replayStruct.mRenderer, saveCount);
Chris Craikc3566d02013-02-04 16:16:33 -0800122 }
123
Chris Craik7273daa2013-03-28 11:25:24 -0700124 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const = 0;
Chris Craik2af46352012-11-26 18:30:17 -0800125};
126
127class DrawOp : public DisplayListOp {
Chris Craik527a3aa2013-03-04 10:19:31 -0800128friend class MergingDrawBatch;
Chris Craik2af46352012-11-26 18:30:17 -0800129public:
130 DrawOp(SkPaint* paint)
131 : mPaint(paint), mQuickRejected(false) {}
132
Chet Haasedd671592013-04-19 14:54:34 -0700133 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
134 bool useQuickReject) {
135 if (mQuickRejected && CC_LIKELY(useQuickReject)) {
Chris Craikff785832013-03-08 13:12:16 -0800136 return;
Chris Craikc3566d02013-02-04 16:16:33 -0800137 }
138
Chris Craikc3566d02013-02-04 16:16:33 -0800139 if (!getLocalBounds(state.mBounds)) {
140 // empty bounds signify bounds can't be calculated
141 state.mBounds.setEmpty();
142 }
143
Chris Craikff785832013-03-08 13:12:16 -0800144 deferStruct.mDeferredList.addDrawOp(deferStruct.mRenderer, this);
Chris Craikc3566d02013-02-04 16:16:33 -0800145 }
146
Chet Haasedd671592013-04-19 14:54:34 -0700147 virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
148 bool useQuickReject) {
149 if (mQuickRejected && CC_LIKELY(useQuickReject)) {
Chris Craikff785832013-03-08 13:12:16 -0800150 return;
151 }
152
Chris Craik527a3aa2013-03-04 10:19:31 -0800153 replayStruct.mDrawGlStatus |= applyDraw(replayStruct.mRenderer, replayStruct.mDirty);
Chris Craikff785832013-03-08 13:12:16 -0800154 }
155
Chris Craik527a3aa2013-03-04 10:19:31 -0800156 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0;
Chris Craik2af46352012-11-26 18:30:17 -0800157
Chris Craik527a3aa2013-03-04 10:19:31 -0800158 /**
159 * Draw multiple instances of an operation, must be overidden for operations that merge
160 *
161 * Currently guarantees certain similarities between ops (see MergingDrawBatch::canMergeWith),
162 * and pure translation transformations. Other guarantees of similarity should be enforced by
163 * reducing which operations are tagged as mergeable.
164 */
165 virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
166 const Vector<DrawOp*>& ops, const Rect& bounds) {
167 status_t status = DrawGlInfo::kStatusDone;
168 for (unsigned int i = 0; i < ops.size(); i++) {
169 renderer.restoreDisplayState(ops[i]->state);
170 status |= ops[i]->applyDraw(renderer, dirty);
171 }
172 return status;
173 }
174
175 /*
176 * When this method is invoked the state field is initialized to have the
177 * final rendering state. We can thus use it to process data as it will be
178 * used at draw time.
179 *
180 * Additionally, this method allows subclasses to provide defer-time preferences for batching
181 * and merging.
182 *
183 * Return true if the op can merge with others of its kind (such subclasses should implement
184 * multiDraw)
185 */
186 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
187 return false;
Romain Guy0f667532013-03-01 14:31:04 -0800188 }
189
Chris Craik2af46352012-11-26 18:30:17 -0800190 // returns true if bounds exist
191 virtual bool getLocalBounds(Rect& localBounds) { return false; }
192
193 // TODO: better refine localbounds usage
194 void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; }
195 bool getQuickRejected() { return mQuickRejected; }
196
Chris Craik527a3aa2013-03-04 10:19:31 -0800197 inline int getPaintAlpha() {
198 return OpenGLRenderer::getAlphaDirect(mPaint);
Chris Craikc3566d02013-02-04 16:16:33 -0800199 }
200
Chris Craik527a3aa2013-03-04 10:19:31 -0800201 inline float strokeWidthOutset() {
Chris Craike7c69c62013-04-03 09:55:48 -0700202 float width = mPaint->getStrokeWidth();
203 if (width == 0) return 0.5f; // account for hairline
204 return width * 0.5f;
205 }
Chris Craikc3566d02013-02-04 16:16:33 -0800206
Chris Craik2af46352012-11-26 18:30:17 -0800207protected:
Chris Craika08f95c2013-03-15 17:24:33 -0700208 SkPaint* getPaint(OpenGLRenderer& renderer) {
209 return renderer.filterPaint(mPaint);
Chris Craik2af46352012-11-26 18:30:17 -0800210 }
211
212 SkPaint* mPaint; // should be accessed via getPaint() when applying
213 bool mQuickRejected;
214};
215
216class DrawBoundedOp : public DrawOp {
217public:
218 DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
219 : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
220
Chris Craik5d116762013-02-19 17:49:31 -0800221 // Calculates bounds as smallest rect encompassing all points
222 // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in
223 // subclass' constructor)
224 DrawBoundedOp(const float* points, int count, SkPaint* paint)
225 : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) {
226 for (int i = 2; i < count; i += 2) {
227 mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
228 mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]);
229 mLocalBounds.top = fminf(mLocalBounds.top, points[i + 1]);
230 mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i + 1]);
231 }
232 }
233
234 // default empty constructor for bounds, to be overridden in child constructor body
Chris Craik2af46352012-11-26 18:30:17 -0800235 DrawBoundedOp(SkPaint* paint)
236 : DrawOp(paint) {}
237
238 bool getLocalBounds(Rect& localBounds) {
239 localBounds.set(mLocalBounds);
240 return true;
241 }
242
Chris Craik527a3aa2013-03-04 10:19:31 -0800243 bool mergeAllowed() {
Chris Craikee5b2c62013-04-18 12:57:07 -0700244 if (!state.mMatrix.isPureTranslate()) return false;
245
Chris Craik527a3aa2013-03-04 10:19:31 -0800246 // checks that we're unclipped, and srcover
247 const Rect& opBounds = state.mBounds;
248 return fabs(opBounds.getWidth() - mLocalBounds.getWidth()) < 0.1 &&
249 fabs(opBounds.getHeight() - mLocalBounds.getHeight()) < 0.1 &&
250 (OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode);
251 }
252
Chris Craik2af46352012-11-26 18:30:17 -0800253protected:
254 Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint
255};
256
257///////////////////////////////////////////////////////////////////////////////
258// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do
259// not directly draw or alter output
260///////////////////////////////////////////////////////////////////////////////
261
262class SaveOp : public StateOp {
Chris Craikff785832013-03-08 13:12:16 -0800263 friend class DisplayList; // give DisplayList private constructor/reinit access
Chris Craik2af46352012-11-26 18:30:17 -0800264public:
265 SaveOp(int flags)
266 : mFlags(flags) {}
267
Chet Haasedd671592013-04-19 14:54:34 -0700268 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
269 bool useQuickReject) {
Chris Craikff785832013-03-08 13:12:16 -0800270 int newSaveCount = deferStruct.mRenderer.save(mFlags);
271 deferStruct.mDeferredList.addSave(deferStruct.mRenderer, this, newSaveCount);
272 }
273
Chris Craik7273daa2013-03-28 11:25:24 -0700274 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800275 renderer.save(mFlags);
276 }
277
Chris Craikff785832013-03-08 13:12:16 -0800278 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800279 OP_LOG("Save flags %x", mFlags);
280 }
281
282 virtual const char* name() { return "Save"; }
283
Chris Craikff785832013-03-08 13:12:16 -0800284 int getFlags() const { return mFlags; }
Chris Craik2af46352012-11-26 18:30:17 -0800285private:
Chris Craikff785832013-03-08 13:12:16 -0800286 SaveOp() {}
287 DisplayListOp* reinit(int flags) {
288 mFlags = flags;
289 return this;
290 }
291
Chris Craik2af46352012-11-26 18:30:17 -0800292 int mFlags;
293};
294
295class RestoreToCountOp : public StateOp {
Chris Craikff785832013-03-08 13:12:16 -0800296 friend class DisplayList; // give DisplayList private constructor/reinit access
Chris Craik2af46352012-11-26 18:30:17 -0800297public:
298 RestoreToCountOp(int count)
299 : mCount(count) {}
300
Chet Haasedd671592013-04-19 14:54:34 -0700301 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
302 bool useQuickReject) {
Chris Craik7273daa2013-03-28 11:25:24 -0700303 deferStruct.mDeferredList.addRestoreToCount(deferStruct.mRenderer,
304 this, saveCount + mCount);
Chris Craikff785832013-03-08 13:12:16 -0800305 deferStruct.mRenderer.restoreToCount(saveCount + mCount);
Chris Craik2af46352012-11-26 18:30:17 -0800306 }
307
Chris Craik7273daa2013-03-28 11:25:24 -0700308 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craikff785832013-03-08 13:12:16 -0800309 renderer.restoreToCount(saveCount + mCount);
310 }
311
312 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800313 OP_LOG("Restore to count %d", mCount);
314 }
315
316 virtual const char* name() { return "RestoreToCount"; }
317
318private:
Chris Craikff785832013-03-08 13:12:16 -0800319 RestoreToCountOp() {}
320 DisplayListOp* reinit(int count) {
321 mCount = count;
322 return this;
323 }
324
Chris Craik2af46352012-11-26 18:30:17 -0800325 int mCount;
326};
327
328class SaveLayerOp : public StateOp {
Chris Craikff785832013-03-08 13:12:16 -0800329 friend class DisplayList; // give DisplayList private constructor/reinit access
Chris Craik2af46352012-11-26 18:30:17 -0800330public:
Chris Craikff785832013-03-08 13:12:16 -0800331 SaveLayerOp(float left, float top, float right, float bottom,
332 int alpha, SkXfermode::Mode mode, int flags)
333 : mArea(left, top, right, bottom), mAlpha(alpha), mMode(mode), mFlags(flags) {}
334
Chet Haasedd671592013-04-19 14:54:34 -0700335 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
336 bool useQuickReject) {
Chris Craikff785832013-03-08 13:12:16 -0800337 // NOTE: don't bother with actual saveLayer, instead issuing it at flush time
Chris Craikd90144d2013-03-19 15:03:48 -0700338 int newSaveCount = deferStruct.mRenderer.getSaveCount();
Chris Craikff785832013-03-08 13:12:16 -0800339 deferStruct.mDeferredList.addSaveLayer(deferStruct.mRenderer, this, newSaveCount);
Chris Craikd90144d2013-03-19 15:03:48 -0700340
341 // NOTE: don't issue full saveLayer, since that has side effects/is costly. instead just
342 // setup the snapshot for deferral, and re-issue the op at flush time
343 deferStruct.mRenderer.saveLayerDeferred(mArea.left, mArea.top, mArea.right, mArea.bottom,
344 mAlpha, mMode, mFlags);
Chris Craikff785832013-03-08 13:12:16 -0800345 }
Chris Craik2af46352012-11-26 18:30:17 -0800346
Chris Craik7273daa2013-03-28 11:25:24 -0700347 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craikff785832013-03-08 13:12:16 -0800348 renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mMode, mFlags);
Chris Craik2af46352012-11-26 18:30:17 -0800349 }
350
Chris Craikff785832013-03-08 13:12:16 -0800351 virtual void output(int level, uint32_t logFlags) {
352 OP_LOG("SaveLayer%s of area " RECT_STRING,
353 (isSaveLayerAlpha() ? "Alpha" : ""),RECT_ARGS(mArea));
Chris Craik2af46352012-11-26 18:30:17 -0800354 }
355
Chris Craikff785832013-03-08 13:12:16 -0800356 virtual const char* name() { return isSaveLayerAlpha() ? "SaveLayerAlpha" : "SaveLayer"; }
357
358 int getFlags() { return mFlags; }
Chris Craik2af46352012-11-26 18:30:17 -0800359
360private:
Chris Craikff785832013-03-08 13:12:16 -0800361 // Special case, reserved for direct DisplayList usage
362 SaveLayerOp() {}
363 DisplayListOp* reinit(float left, float top, float right, float bottom,
364 int alpha, SkXfermode::Mode mode, int flags) {
365 mArea.set(left, top, right, bottom);
366 mAlpha = alpha;
367 mMode = mode;
368 mFlags = flags;
369 return this;
Chris Craik2af46352012-11-26 18:30:17 -0800370 }
371
Chris Craikff785832013-03-08 13:12:16 -0800372 bool isSaveLayerAlpha() { return mAlpha < 255 && mMode == SkXfermode::kSrcOver_Mode; }
Chris Craik2af46352012-11-26 18:30:17 -0800373 Rect mArea;
374 int mAlpha;
Chris Craikff785832013-03-08 13:12:16 -0800375 SkXfermode::Mode mMode;
Chris Craik2af46352012-11-26 18:30:17 -0800376 int mFlags;
377};
378
379class TranslateOp : public StateOp {
380public:
381 TranslateOp(float dx, float dy)
382 : mDx(dx), mDy(dy) {}
383
Chris Craik7273daa2013-03-28 11:25:24 -0700384 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800385 renderer.translate(mDx, mDy);
386 }
387
Chris Craikff785832013-03-08 13:12:16 -0800388 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800389 OP_LOG("Translate by %f %f", mDx, mDy);
390 }
391
392 virtual const char* name() { return "Translate"; }
393
394private:
395 float mDx;
396 float mDy;
397};
398
399class RotateOp : public StateOp {
400public:
401 RotateOp(float degrees)
402 : mDegrees(degrees) {}
403
Chris Craik7273daa2013-03-28 11:25:24 -0700404 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800405 renderer.rotate(mDegrees);
406 }
407
Chris Craikff785832013-03-08 13:12:16 -0800408 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800409 OP_LOG("Rotate by %f degrees", mDegrees);
410 }
411
412 virtual const char* name() { return "Rotate"; }
413
414private:
415 float mDegrees;
416};
417
418class ScaleOp : public StateOp {
419public:
420 ScaleOp(float sx, float sy)
421 : mSx(sx), mSy(sy) {}
422
Chris Craik7273daa2013-03-28 11:25:24 -0700423 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800424 renderer.scale(mSx, mSy);
425 }
426
Chris Craikff785832013-03-08 13:12:16 -0800427 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800428 OP_LOG("Scale by %f %f", mSx, mSy);
429 }
430
431 virtual const char* name() { return "Scale"; }
432
433private:
434 float mSx;
435 float mSy;
436};
437
438class SkewOp : public StateOp {
439public:
440 SkewOp(float sx, float sy)
441 : mSx(sx), mSy(sy) {}
442
Chris Craik7273daa2013-03-28 11:25:24 -0700443 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800444 renderer.skew(mSx, mSy);
445 }
446
Chris Craikff785832013-03-08 13:12:16 -0800447 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800448 OP_LOG("Skew by %f %f", mSx, mSy);
449 }
450
451 virtual const char* name() { return "Skew"; }
452
453private:
454 float mSx;
455 float mSy;
456};
457
458class SetMatrixOp : public StateOp {
459public:
460 SetMatrixOp(SkMatrix* matrix)
461 : mMatrix(matrix) {}
462
Chris Craik7273daa2013-03-28 11:25:24 -0700463 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800464 renderer.setMatrix(mMatrix);
465 }
466
Chris Craikff785832013-03-08 13:12:16 -0800467 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800468 OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
469 }
470
471 virtual const char* name() { return "SetMatrix"; }
472
473private:
474 SkMatrix* mMatrix;
475};
476
477class ConcatMatrixOp : public StateOp {
478public:
479 ConcatMatrixOp(SkMatrix* matrix)
480 : mMatrix(matrix) {}
481
Chris Craik7273daa2013-03-28 11:25:24 -0700482 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800483 renderer.concatMatrix(mMatrix);
484 }
485
Chris Craikff785832013-03-08 13:12:16 -0800486 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800487 OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
488 }
489
490 virtual const char* name() { return "ConcatMatrix"; }
491
492private:
493 SkMatrix* mMatrix;
494};
495
Chris Craikff785832013-03-08 13:12:16 -0800496class ClipOp : public StateOp {
497public:
498 ClipOp(SkRegion::Op op) : mOp(op) {}
499
Chet Haasedd671592013-04-19 14:54:34 -0700500 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
501 bool useQuickReject) {
Chris Craikff785832013-03-08 13:12:16 -0800502 // NOTE: must defer op BEFORE applying state, since it may read clip
503 deferStruct.mDeferredList.addClip(deferStruct.mRenderer, this);
504
505 // TODO: Can we avoid applying complex clips at defer time?
506 applyState(deferStruct.mRenderer, saveCount);
507 }
508
509 bool canCauseComplexClip() {
510 return ((mOp != SkRegion::kIntersect_Op) && (mOp != SkRegion::kReplace_Op)) || !isRect();
511 }
512
513protected:
514 ClipOp() {}
515 virtual bool isRect() { return false; }
516
517 SkRegion::Op mOp;
518};
519
520class ClipRectOp : public ClipOp {
521 friend class DisplayList; // give DisplayList private constructor/reinit access
Chris Craik2af46352012-11-26 18:30:17 -0800522public:
523 ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op)
Chris Craikff785832013-03-08 13:12:16 -0800524 : ClipOp(op), mArea(left, top, right, bottom) {}
Chris Craik2af46352012-11-26 18:30:17 -0800525
Chris Craik7273daa2013-03-28 11:25:24 -0700526 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800527 renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp);
528 }
529
Chris Craikff785832013-03-08 13:12:16 -0800530 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800531 OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea));
532 }
533
534 virtual const char* name() { return "ClipRect"; }
535
Chris Craikff785832013-03-08 13:12:16 -0800536protected:
537 virtual bool isRect() { return true; }
Chris Craikb98a0162013-02-21 11:30:22 -0800538
Chris Craik2af46352012-11-26 18:30:17 -0800539private:
Chris Craikff785832013-03-08 13:12:16 -0800540 ClipRectOp() {}
541 DisplayListOp* reinit(float left, float top, float right, float bottom, SkRegion::Op op) {
542 mOp = op;
543 mArea.set(left, top, right, bottom);
544 return this;
Chris Craikb98a0162013-02-21 11:30:22 -0800545 }
Chris Craikff785832013-03-08 13:12:16 -0800546
Chris Craik2af46352012-11-26 18:30:17 -0800547 Rect mArea;
Chris Craik2af46352012-11-26 18:30:17 -0800548};
549
Chris Craikff785832013-03-08 13:12:16 -0800550class ClipPathOp : public ClipOp {
Chris Craik2af46352012-11-26 18:30:17 -0800551public:
552 ClipPathOp(SkPath* path, SkRegion::Op op)
Chris Craikff785832013-03-08 13:12:16 -0800553 : ClipOp(op), mPath(path) {}
Chris Craik2af46352012-11-26 18:30:17 -0800554
Chris Craik7273daa2013-03-28 11:25:24 -0700555 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800556 renderer.clipPath(mPath, mOp);
557 }
558
Chris Craikff785832013-03-08 13:12:16 -0800559 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800560 SkRect bounds = mPath->getBounds();
561 OP_LOG("ClipPath bounds " RECT_STRING,
562 bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
563 }
564
565 virtual const char* name() { return "ClipPath"; }
566
567private:
568 SkPath* mPath;
Chris Craik2af46352012-11-26 18:30:17 -0800569};
570
Chris Craikff785832013-03-08 13:12:16 -0800571class ClipRegionOp : public ClipOp {
Chris Craik2af46352012-11-26 18:30:17 -0800572public:
573 ClipRegionOp(SkRegion* region, SkRegion::Op op)
Chris Craikff785832013-03-08 13:12:16 -0800574 : ClipOp(op), mRegion(region) {}
Chris Craik2af46352012-11-26 18:30:17 -0800575
Chris Craik7273daa2013-03-28 11:25:24 -0700576 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800577 renderer.clipRegion(mRegion, mOp);
578 }
579
Chris Craikff785832013-03-08 13:12:16 -0800580 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800581 SkIRect bounds = mRegion->getBounds();
582 OP_LOG("ClipRegion bounds %d %d %d %d",
583 bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
584 }
585
586 virtual const char* name() { return "ClipRegion"; }
587
588private:
589 SkRegion* mRegion;
590 SkRegion::Op mOp;
591};
592
593class ResetShaderOp : public StateOp {
594public:
Chris Craik7273daa2013-03-28 11:25:24 -0700595 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800596 renderer.resetShader();
597 }
598
Chris Craikff785832013-03-08 13:12:16 -0800599 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800600 OP_LOGS("ResetShader");
601 }
602
603 virtual const char* name() { return "ResetShader"; }
604};
605
606class SetupShaderOp : public StateOp {
607public:
608 SetupShaderOp(SkiaShader* shader)
609 : mShader(shader) {}
Chris Craik7273daa2013-03-28 11:25:24 -0700610 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800611 renderer.setupShader(mShader);
612 }
613
Chris Craikff785832013-03-08 13:12:16 -0800614 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800615 OP_LOG("SetupShader, shader %p", mShader);
616 }
617
618 virtual const char* name() { return "SetupShader"; }
619
620private:
621 SkiaShader* mShader;
622};
623
624class ResetColorFilterOp : public StateOp {
625public:
Chris Craik7273daa2013-03-28 11:25:24 -0700626 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800627 renderer.resetColorFilter();
628 }
629
Chris Craikff785832013-03-08 13:12:16 -0800630 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800631 OP_LOGS("ResetColorFilter");
632 }
633
634 virtual const char* name() { return "ResetColorFilter"; }
635};
636
637class SetupColorFilterOp : public StateOp {
638public:
639 SetupColorFilterOp(SkiaColorFilter* colorFilter)
640 : mColorFilter(colorFilter) {}
641
Chris Craik7273daa2013-03-28 11:25:24 -0700642 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800643 renderer.setupColorFilter(mColorFilter);
644 }
645
Chris Craikff785832013-03-08 13:12:16 -0800646 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800647 OP_LOG("SetupColorFilter, filter %p", mColorFilter);
648 }
649
650 virtual const char* name() { return "SetupColorFilter"; }
651
652private:
653 SkiaColorFilter* mColorFilter;
654};
655
656class ResetShadowOp : public StateOp {
657public:
Chris Craik7273daa2013-03-28 11:25:24 -0700658 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800659 renderer.resetShadow();
660 }
661
Chris Craikff785832013-03-08 13:12:16 -0800662 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800663 OP_LOGS("ResetShadow");
664 }
665
666 virtual const char* name() { return "ResetShadow"; }
667};
668
669class SetupShadowOp : public StateOp {
670public:
671 SetupShadowOp(float radius, float dx, float dy, int color)
672 : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {}
673
Chris Craik7273daa2013-03-28 11:25:24 -0700674 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800675 renderer.setupShadow(mRadius, mDx, mDy, mColor);
676 }
677
Chris Craikff785832013-03-08 13:12:16 -0800678 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800679 OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor);
680 }
681
682 virtual const char* name() { return "SetupShadow"; }
683
684private:
685 float mRadius;
686 float mDx;
687 float mDy;
688 int mColor;
689};
690
691class ResetPaintFilterOp : public StateOp {
692public:
Chris Craik7273daa2013-03-28 11:25:24 -0700693 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800694 renderer.resetPaintFilter();
695 }
696
Chris Craikff785832013-03-08 13:12:16 -0800697 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800698 OP_LOGS("ResetPaintFilter");
699 }
700
701 virtual const char* name() { return "ResetPaintFilter"; }
702};
703
704class SetupPaintFilterOp : public StateOp {
705public:
706 SetupPaintFilterOp(int clearBits, int setBits)
707 : mClearBits(clearBits), mSetBits(setBits) {}
708
Chris Craik7273daa2013-03-28 11:25:24 -0700709 virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
Chris Craik2af46352012-11-26 18:30:17 -0800710 renderer.setupPaintFilter(mClearBits, mSetBits);
711 }
712
Chris Craikff785832013-03-08 13:12:16 -0800713 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800714 OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits);
715 }
716
717 virtual const char* name() { return "SetupPaintFilter"; }
718
719private:
720 int mClearBits;
721 int mSetBits;
722};
723
724
725///////////////////////////////////////////////////////////////////////////////
726// DRAW OPERATIONS - these are operations that can draw to the canvas's device
727///////////////////////////////////////////////////////////////////////////////
728
729class DrawBitmapOp : public DrawBoundedOp {
730public:
731 DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
732 : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(),
733 paint),
734 mBitmap(bitmap) {}
735
Chris Craik527a3aa2013-03-04 10:19:31 -0800736 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craika08f95c2013-03-15 17:24:33 -0700737 return renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top,
738 getPaint(renderer));
Chris Craik2af46352012-11-26 18:30:17 -0800739 }
740
Chris Craik527a3aa2013-03-04 10:19:31 -0800741#define SET_TEXTURE(ptr, posRect, offsetRect, texCoordsRect, xDim, yDim) \
742 TextureVertex::set(ptr++, posRect.xDim - offsetRect.left, posRect.yDim - offsetRect.top, \
743 texCoordsRect.xDim, texCoordsRect.yDim)
744
745 virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
746 const Vector<DrawOp*>& ops, const Rect& bounds) {
747 renderer.restoreDisplayState(state, true); // restore all but the clip
748 renderer.setFullScreenClip(); // ensure merged ops aren't clipped
749 TextureVertex vertices[6 * ops.size()];
750 TextureVertex* vertex = &vertices[0];
751
752 // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op, and allowing
753 // them to be merged in getBatchId()
754 const Rect texCoords(0, 0, 1, 1);
755
756 const float width = mBitmap->width();
757 const float height = mBitmap->height();
758 for (unsigned int i = 0; i < ops.size(); i++) {
759 const Rect& opBounds = ops[i]->state.mBounds;
760 SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
761 SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
762 SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom);
763
764 SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom);
765 SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
766 SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom);
767 }
768
769 return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0], bounds, mPaint);
770 }
771
Chris Craikff785832013-03-08 13:12:16 -0800772 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800773 OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top);
774 }
775
776 virtual const char* name() { return "DrawBitmap"; }
Chris Craik527a3aa2013-03-04 10:19:31 -0800777
778 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
779 *batchId = DeferredDisplayList::kOpBatch_Bitmap;
780 *mergeId = (mergeid_t)mBitmap;
781
782 // don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
783 // MergingDrawBatch::canMergeWith
784 return mergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config);
Chris Craikc3566d02013-02-04 16:16:33 -0800785 }
Chris Craik2af46352012-11-26 18:30:17 -0800786
Chris Craik527a3aa2013-03-04 10:19:31 -0800787 const SkBitmap* bitmap() { return mBitmap; }
Chris Craik2af46352012-11-26 18:30:17 -0800788protected:
789 SkBitmap* mBitmap;
790};
791
792class DrawBitmapMatrixOp : public DrawBoundedOp {
793public:
794 DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint)
795 : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
796 mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
797 const mat4 transform(*matrix);
798 transform.mapRect(mLocalBounds);
799 }
800
Chris Craik527a3aa2013-03-04 10:19:31 -0800801 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -0800802 return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer));
803 }
804
Chris Craikff785832013-03-08 13:12:16 -0800805 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800806 OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix));
807 }
808
Chris Craik527a3aa2013-03-04 10:19:31 -0800809 virtual const char* name() { return "DrawBitmapMatrix"; }
810
811 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
812 *batchId = DeferredDisplayList::kOpBatch_Bitmap;
813 return false;
Chris Craikc3566d02013-02-04 16:16:33 -0800814 }
Chris Craik2af46352012-11-26 18:30:17 -0800815
816private:
817 SkBitmap* mBitmap;
818 SkMatrix* mMatrix;
819};
820
821class DrawBitmapRectOp : public DrawBoundedOp {
822public:
823 DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom,
824 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint)
825 : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
826 mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
827
Chris Craik527a3aa2013-03-04 10:19:31 -0800828 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -0800829 return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
830 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
831 getPaint(renderer));
832 }
833
Chris Craikff785832013-03-08 13:12:16 -0800834 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800835 OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING,
836 mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds));
837 }
838
839 virtual const char* name() { return "DrawBitmapRect"; }
Chris Craik527a3aa2013-03-04 10:19:31 -0800840
841 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
842 *batchId = DeferredDisplayList::kOpBatch_Bitmap;
843 return false;
Chris Craikc3566d02013-02-04 16:16:33 -0800844 }
Chris Craik2af46352012-11-26 18:30:17 -0800845
846private:
847 SkBitmap* mBitmap;
848 Rect mSrc;
849};
850
851class DrawBitmapDataOp : public DrawBitmapOp {
852public:
853 DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
854 : DrawBitmapOp(bitmap, left, top, paint) {}
855
Chris Craik527a3aa2013-03-04 10:19:31 -0800856 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -0800857 return renderer.drawBitmapData(mBitmap, mLocalBounds.left,
858 mLocalBounds.top, getPaint(renderer));
859 }
860
Chris Craikff785832013-03-08 13:12:16 -0800861 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800862 OP_LOG("Draw bitmap %p", mBitmap);
863 }
864
865 virtual const char* name() { return "DrawBitmapData"; }
Chris Craik527a3aa2013-03-04 10:19:31 -0800866
867 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
868 *batchId = DeferredDisplayList::kOpBatch_Bitmap;
869 return false;
Chris Craikc3566d02013-02-04 16:16:33 -0800870 }
Chris Craik2af46352012-11-26 18:30:17 -0800871};
872
Chris Craik5d116762013-02-19 17:49:31 -0800873class DrawBitmapMeshOp : public DrawBoundedOp {
Chris Craik2af46352012-11-26 18:30:17 -0800874public:
875 DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight,
876 float* vertices, int* colors, SkPaint* paint)
Chris Craik5d116762013-02-19 17:49:31 -0800877 : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint),
878 mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
Chris Craik2af46352012-11-26 18:30:17 -0800879 mVertices(vertices), mColors(colors) {}
880
Chris Craik527a3aa2013-03-04 10:19:31 -0800881 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -0800882 return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
883 mVertices, mColors, getPaint(renderer));
884 }
885
Chris Craikff785832013-03-08 13:12:16 -0800886 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800887 OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight);
888 }
889
890 virtual const char* name() { return "DrawBitmapMesh"; }
Chris Craik527a3aa2013-03-04 10:19:31 -0800891
892 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
893 *batchId = DeferredDisplayList::kOpBatch_Bitmap;
894 return false;
Chris Craikc3566d02013-02-04 16:16:33 -0800895 }
Chris Craik2af46352012-11-26 18:30:17 -0800896
897private:
898 SkBitmap* mBitmap;
899 int mMeshWidth;
900 int mMeshHeight;
901 float* mVertices;
902 int* mColors;
903};
904
905class DrawPatchOp : public DrawBoundedOp {
906public:
907 DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs,
908 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
909 int8_t numColors, float left, float top, float right, float bottom,
910 int alpha, SkXfermode::Mode mode)
911 : DrawBoundedOp(left, top, right, bottom, 0),
912 mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs),
913 mColors(colors), mxDivsCount(width), myDivsCount(height),
914 mNumColors(numColors), mAlpha(alpha), mMode(mode) {};
915
Chris Craik527a3aa2013-03-04 10:19:31 -0800916 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -0800917 // NOTE: not calling the virtual method, which takes a paint
918 return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors,
919 mxDivsCount, myDivsCount, mNumColors,
920 mLocalBounds.left, mLocalBounds.top,
921 mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode);
922 }
923
Chris Craikff785832013-03-08 13:12:16 -0800924 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800925 OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds));
926 }
927
928 virtual const char* name() { return "DrawPatch"; }
Chris Craik527a3aa2013-03-04 10:19:31 -0800929
930 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
931 *batchId = DeferredDisplayList::kOpBatch_Patch;
932 *mergeId = (mergeid_t)mBitmap;
933 return true;
Chris Craikc3566d02013-02-04 16:16:33 -0800934 }
Chris Craik2af46352012-11-26 18:30:17 -0800935
936private:
937 SkBitmap* mBitmap;
938 const int32_t* mxDivs;
939 const int32_t* myDivs;
940 const uint32_t* mColors;
941 uint32_t mxDivsCount;
942 uint32_t myDivsCount;
943 int8_t mNumColors;
944 int mAlpha;
945 SkXfermode::Mode mMode;
946};
947
948class DrawColorOp : public DrawOp {
949public:
950 DrawColorOp(int color, SkXfermode::Mode mode)
951 : DrawOp(0), mColor(color), mMode(mode) {};
952
Chris Craik527a3aa2013-03-04 10:19:31 -0800953 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -0800954 return renderer.drawColor(mColor, mMode);
955 }
956
Chris Craikff785832013-03-08 13:12:16 -0800957 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -0800958 OP_LOG("Draw color %#x, mode %d", mColor, mMode);
959 }
960
961 virtual const char* name() { return "DrawColor"; }
962
963private:
964 int mColor;
965 SkXfermode::Mode mMode;
966};
967
968class DrawStrokableOp : public DrawBoundedOp {
969public:
970 DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
971 : DrawBoundedOp(left, top, right, bottom, paint) {};
972
973 bool getLocalBounds(Rect& localBounds) {
Chris Craikc3566d02013-02-04 16:16:33 -0800974 localBounds.set(mLocalBounds);
Chris Craik2af46352012-11-26 18:30:17 -0800975 if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
Chris Craikc3566d02013-02-04 16:16:33 -0800976 localBounds.outset(strokeWidthOutset());
Chris Craik2af46352012-11-26 18:30:17 -0800977 }
978 return true;
979 }
Chris Craikc3566d02013-02-04 16:16:33 -0800980
Chris Craik527a3aa2013-03-04 10:19:31 -0800981 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
Chris Craikc3566d02013-02-04 16:16:33 -0800982 if (mPaint->getPathEffect()) {
Chris Craik527a3aa2013-03-04 10:19:31 -0800983 *batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
984 } else {
985 *batchId = mPaint->isAntiAlias() ?
986 DeferredDisplayList::kOpBatch_AlphaVertices :
987 DeferredDisplayList::kOpBatch_Vertices;
Chris Craikc3566d02013-02-04 16:16:33 -0800988 }
Chris Craik527a3aa2013-03-04 10:19:31 -0800989 return false;
Chris Craikc3566d02013-02-04 16:16:33 -0800990 }
Chris Craik2af46352012-11-26 18:30:17 -0800991};
992
993class DrawRectOp : public DrawStrokableOp {
994public:
995 DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint)
996 : DrawStrokableOp(left, top, right, bottom, paint) {}
997
Chris Craik527a3aa2013-03-04 10:19:31 -0800998 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -0800999 return renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
1000 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
1001 }
1002
Chris Craikff785832013-03-08 13:12:16 -08001003 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001004 OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds));
1005 }
1006
1007 virtual const char* name() { return "DrawRect"; }
1008};
1009
Chris Craik5d116762013-02-19 17:49:31 -08001010class DrawRectsOp : public DrawBoundedOp {
Chris Craik2af46352012-11-26 18:30:17 -08001011public:
1012 DrawRectsOp(const float* rects, int count, SkPaint* paint)
Chris Craik5d116762013-02-19 17:49:31 -08001013 : DrawBoundedOp(rects, count, paint),
1014 mRects(rects), mCount(count) {}
Chris Craik2af46352012-11-26 18:30:17 -08001015
Chris Craik527a3aa2013-03-04 10:19:31 -08001016 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001017 return renderer.drawRects(mRects, mCount, getPaint(renderer));
1018 }
1019
Chris Craikff785832013-03-08 13:12:16 -08001020 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001021 OP_LOG("Draw Rects count %d", mCount);
1022 }
1023
1024 virtual const char* name() { return "DrawRects"; }
1025
Chris Craik527a3aa2013-03-04 10:19:31 -08001026 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
1027 *batchId = DeferredDisplayList::kOpBatch_Vertices;
1028 return false;
Chris Craikc3566d02013-02-04 16:16:33 -08001029 }
1030
Chris Craik2af46352012-11-26 18:30:17 -08001031private:
1032 const float* mRects;
1033 int mCount;
1034};
1035
1036class DrawRoundRectOp : public DrawStrokableOp {
1037public:
1038 DrawRoundRectOp(float left, float top, float right, float bottom,
1039 float rx, float ry, SkPaint* paint)
1040 : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
1041
Chris Craik527a3aa2013-03-04 10:19:31 -08001042 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001043 return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
1044 mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer));
1045 }
1046
Chris Craikff785832013-03-08 13:12:16 -08001047 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001048 OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy);
1049 }
1050
1051 virtual const char* name() { return "DrawRoundRect"; }
1052
1053private:
1054 float mRx;
1055 float mRy;
1056};
1057
1058class DrawCircleOp : public DrawStrokableOp {
1059public:
1060 DrawCircleOp(float x, float y, float radius, SkPaint* paint)
1061 : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
1062 mX(x), mY(y), mRadius(radius) {}
1063
Chris Craik527a3aa2013-03-04 10:19:31 -08001064 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001065 return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer));
1066 }
1067
Chris Craikff785832013-03-08 13:12:16 -08001068 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001069 OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius);
1070 }
1071
1072 virtual const char* name() { return "DrawCircle"; }
1073
1074private:
1075 float mX;
1076 float mY;
1077 float mRadius;
1078};
1079
1080class DrawOvalOp : public DrawStrokableOp {
1081public:
1082 DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint)
1083 : DrawStrokableOp(left, top, right, bottom, paint) {}
1084
Chris Craik527a3aa2013-03-04 10:19:31 -08001085 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001086 return renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
1087 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
1088 }
1089
Chris Craikff785832013-03-08 13:12:16 -08001090 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001091 OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds));
1092 }
1093
1094 virtual const char* name() { return "DrawOval"; }
1095};
1096
1097class DrawArcOp : public DrawStrokableOp {
1098public:
1099 DrawArcOp(float left, float top, float right, float bottom,
1100 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint)
1101 : DrawStrokableOp(left, top, right, bottom, paint),
1102 mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
1103
Chris Craik527a3aa2013-03-04 10:19:31 -08001104 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001105 return renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
1106 mLocalBounds.right, mLocalBounds.bottom,
1107 mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer));
1108 }
1109
Chris Craikff785832013-03-08 13:12:16 -08001110 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001111 OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d",
1112 RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter);
1113 }
1114
1115 virtual const char* name() { return "DrawArc"; }
1116
1117private:
1118 float mStartAngle;
1119 float mSweepAngle;
1120 bool mUseCenter;
1121};
1122
1123class DrawPathOp : public DrawBoundedOp {
1124public:
1125 DrawPathOp(SkPath* path, SkPaint* paint)
1126 : DrawBoundedOp(paint), mPath(path) {
1127 float left, top, offset;
1128 uint32_t width, height;
Romain Guyca89e2a2013-03-08 17:44:20 -08001129 PathCache::computePathBounds(path, paint, left, top, offset, width, height);
Chris Craik2af46352012-11-26 18:30:17 -08001130 left -= offset;
1131 top -= offset;
1132 mLocalBounds.set(left, top, left + width, top + height);
1133 }
1134
Chris Craik527a3aa2013-03-04 10:19:31 -08001135 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001136 return renderer.drawPath(mPath, getPaint(renderer));
1137 }
1138
Chris Craik527a3aa2013-03-04 10:19:31 -08001139 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
Romain Guyca89e2a2013-03-08 17:44:20 -08001140 SkPaint* paint = getPaint(renderer);
1141 renderer.getCaches().pathCache.precache(mPath, paint);
Chris Craik527a3aa2013-03-04 10:19:31 -08001142
1143 *batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
1144 return false;
Romain Guyca89e2a2013-03-08 17:44:20 -08001145 }
1146
Chris Craikff785832013-03-08 13:12:16 -08001147 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001148 OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds));
1149 }
1150
1151 virtual const char* name() { return "DrawPath"; }
1152
1153private:
1154 SkPath* mPath;
1155};
1156
Chris Craikc3566d02013-02-04 16:16:33 -08001157class DrawLinesOp : public DrawBoundedOp {
Chris Craik2af46352012-11-26 18:30:17 -08001158public:
1159 DrawLinesOp(float* points, int count, SkPaint* paint)
Chris Craik5d116762013-02-19 17:49:31 -08001160 : DrawBoundedOp(points, count, paint),
1161 mPoints(points), mCount(count) {
Chris Craikc3566d02013-02-04 16:16:33 -08001162 mLocalBounds.outset(strokeWidthOutset());
Chris Craik2af46352012-11-26 18:30:17 -08001163 }
1164
Chris Craik527a3aa2013-03-04 10:19:31 -08001165 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001166 return renderer.drawLines(mPoints, mCount, getPaint(renderer));
1167 }
1168
Chris Craikff785832013-03-08 13:12:16 -08001169 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001170 OP_LOG("Draw Lines count %d", mCount);
1171 }
1172
1173 virtual const char* name() { return "DrawLines"; }
1174
Chris Craik527a3aa2013-03-04 10:19:31 -08001175 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
1176 *batchId = mPaint->isAntiAlias() ?
Chris Craikc3566d02013-02-04 16:16:33 -08001177 DeferredDisplayList::kOpBatch_AlphaVertices :
1178 DeferredDisplayList::kOpBatch_Vertices;
Chris Craik527a3aa2013-03-04 10:19:31 -08001179 return false;
Chris Craikc3566d02013-02-04 16:16:33 -08001180 }
1181
Chris Craik2af46352012-11-26 18:30:17 -08001182protected:
1183 float* mPoints;
1184 int mCount;
1185};
1186
1187class DrawPointsOp : public DrawLinesOp {
1188public:
1189 DrawPointsOp(float* points, int count, SkPaint* paint)
1190 : DrawLinesOp(points, count, paint) {}
1191
Chris Craik527a3aa2013-03-04 10:19:31 -08001192 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001193 return renderer.drawPoints(mPoints, mCount, getPaint(renderer));
1194 }
1195
Chris Craikff785832013-03-08 13:12:16 -08001196 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001197 OP_LOG("Draw Points count %d", mCount);
1198 }
1199
1200 virtual const char* name() { return "DrawPoints"; }
1201};
1202
1203class DrawSomeTextOp : public DrawOp {
1204public:
1205 DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint)
1206 : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
1207
Chris Craikff785832013-03-08 13:12:16 -08001208 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001209 OP_LOG("Draw some text, %d bytes", mBytesCount);
1210 }
Chris Craikc3566d02013-02-04 16:16:33 -08001211
Chris Craik527a3aa2013-03-04 10:19:31 -08001212 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
Romain Guy0f667532013-03-01 14:31:04 -08001213 SkPaint* paint = getPaint(renderer);
1214 FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
1215 fontRenderer.precache(paint, mText, mCount, mat4::identity());
Romain Guy0f667532013-03-01 14:31:04 -08001216
Chris Craik527a3aa2013-03-04 10:19:31 -08001217 *batchId = mPaint->getColor() == 0xff000000 ?
Chris Craikc3566d02013-02-04 16:16:33 -08001218 DeferredDisplayList::kOpBatch_Text :
1219 DeferredDisplayList::kOpBatch_ColorText;
Chris Craik527a3aa2013-03-04 10:19:31 -08001220
1221 return false;
Chris Craikc3566d02013-02-04 16:16:33 -08001222 }
Chris Craik527a3aa2013-03-04 10:19:31 -08001223
Chris Craik2af46352012-11-26 18:30:17 -08001224protected:
1225 const char* mText;
1226 int mBytesCount;
1227 int mCount;
1228};
1229
1230class DrawTextOnPathOp : public DrawSomeTextOp {
1231public:
1232 DrawTextOnPathOp(const char* text, int bytesCount, int count,
1233 SkPath* path, float hOffset, float vOffset, SkPaint* paint)
1234 : DrawSomeTextOp(text, bytesCount, count, paint),
1235 mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
1236 /* TODO: inherit from DrawBounded and init mLocalBounds */
1237 }
1238
Chris Craik527a3aa2013-03-04 10:19:31 -08001239 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001240 return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
1241 mHOffset, mVOffset, getPaint(renderer));
1242 }
1243
1244 virtual const char* name() { return "DrawTextOnPath"; }
1245
1246private:
1247 SkPath* mPath;
1248 float mHOffset;
1249 float mVOffset;
1250};
1251
1252class DrawPosTextOp : public DrawSomeTextOp {
1253public:
1254 DrawPosTextOp(const char* text, int bytesCount, int count,
1255 const float* positions, SkPaint* paint)
1256 : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) {
1257 /* TODO: inherit from DrawBounded and init mLocalBounds */
1258 }
1259
Chris Craik527a3aa2013-03-04 10:19:31 -08001260 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001261 return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer));
1262 }
1263
1264 virtual const char* name() { return "DrawPosText"; }
1265
1266private:
1267 const float* mPositions;
1268};
1269
1270class DrawTextOp : public DrawBoundedOp {
1271public:
1272 DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
1273 const float* positions, SkPaint* paint, float length)
1274 : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count),
1275 mX(x), mY(y), mPositions(positions), mLength(length) {
Chris Craikd6960a42013-02-28 11:25:39 -08001276 // duplicates bounds calculation from OpenGLRenderer::drawText, but doesn't alter mX
Chris Craik2af46352012-11-26 18:30:17 -08001277 SkPaint::FontMetrics metrics;
1278 paint->getFontMetrics(&metrics, 0.0f);
Chris Craikd6960a42013-02-28 11:25:39 -08001279 switch (paint->getTextAlign()) {
1280 case SkPaint::kCenter_Align:
1281 x -= length / 2.0f;
1282 break;
1283 case SkPaint::kRight_Align:
1284 x -= length;
1285 break;
1286 default:
1287 break;
1288 }
1289 mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom);
Romain Guybd3055f2013-03-13 16:14:47 -07001290 memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float));
Chris Craik2af46352012-11-26 18:30:17 -08001291 }
1292
Chris Craik527a3aa2013-03-04 10:19:31 -08001293 virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
Romain Guy0f667532013-03-01 14:31:04 -08001294 SkPaint* paint = getPaint(renderer);
1295 FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
Romain Guybd3055f2013-03-13 16:14:47 -07001296 const mat4& transform = renderer.findBestFontTransform(state.mMatrix);
1297 if (mPrecacheTransform != transform) {
1298 fontRenderer.precache(paint, mText, mCount, transform);
1299 mPrecacheTransform = transform;
1300 }
Chris Craik527a3aa2013-03-04 10:19:31 -08001301 *batchId = mPaint->getColor() == 0xff000000 ?
1302 DeferredDisplayList::kOpBatch_Text :
1303 DeferredDisplayList::kOpBatch_ColorText;
1304
1305 *mergeId = (mergeid_t)mPaint->getColor();
1306
1307 // don't merge decorated text - the decorations won't draw in order
1308 bool noDecorations = !(mPaint->getFlags() & (SkPaint::kUnderlineText_Flag |
1309 SkPaint::kStrikeThruText_Flag));
1310 return mergeAllowed() && noDecorations;
Romain Guy0f667532013-03-01 14:31:04 -08001311 }
1312
Chris Craik527a3aa2013-03-04 10:19:31 -08001313 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001314 return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
1315 mPositions, getPaint(renderer), mLength);
1316 }
1317
Chris Craik527a3aa2013-03-04 10:19:31 -08001318 virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
1319 const Vector<DrawOp*>& ops, const Rect& bounds) {
1320 status_t status = DrawGlInfo::kStatusDone;
1321 renderer.setFullScreenClip(); // ensure merged ops aren't clipped
1322 for (unsigned int i = 0; i < ops.size(); i++) {
1323 DrawOpMode drawOpMode = (i == ops.size() - 1) ? kDrawOpMode_Flush : kDrawOpMode_Defer;
1324 renderer.restoreDisplayState(ops[i]->state, true); // restore all but the clip
1325
1326 DrawTextOp& op = *((DrawTextOp*)ops[i]);
1327 status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
1328 op.mPositions, op.getPaint(renderer), op.mLength, drawOpMode);
1329 }
1330 return status;
1331 }
1332
Chris Craikff785832013-03-08 13:12:16 -08001333 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001334 OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount);
1335 }
1336
1337 virtual const char* name() { return "DrawText"; }
1338
1339private:
1340 const char* mText;
1341 int mBytesCount;
1342 int mCount;
1343 float mX;
1344 float mY;
1345 const float* mPositions;
1346 float mLength;
Romain Guybd3055f2013-03-13 16:14:47 -07001347 mat4 mPrecacheTransform;
Chris Craik2af46352012-11-26 18:30:17 -08001348};
1349
1350///////////////////////////////////////////////////////////////////////////////
1351// SPECIAL DRAW OPERATIONS
1352///////////////////////////////////////////////////////////////////////////////
1353
1354class DrawFunctorOp : public DrawOp {
1355public:
1356 DrawFunctorOp(Functor* functor)
1357 : DrawOp(0), mFunctor(functor) {}
1358
Chris Craik527a3aa2013-03-04 10:19:31 -08001359 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craik2af46352012-11-26 18:30:17 -08001360 renderer.startMark("GL functor");
1361 status_t ret = renderer.callDrawGLFunction(mFunctor, dirty);
1362 renderer.endMark();
1363 return ret;
1364 }
1365
Chris Craikff785832013-03-08 13:12:16 -08001366 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001367 OP_LOG("Draw Functor %p", mFunctor);
1368 }
1369
1370 virtual const char* name() { return "DrawFunctor"; }
1371
1372private:
1373 Functor* mFunctor;
1374};
1375
Chris Craik5d116762013-02-19 17:49:31 -08001376class DrawDisplayListOp : public DrawBoundedOp {
Chris Craik2af46352012-11-26 18:30:17 -08001377public:
1378 DrawDisplayListOp(DisplayList* displayList, int flags)
Chris Craik5d116762013-02-19 17:49:31 -08001379 : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0),
1380 mDisplayList(displayList), mFlags(flags) {}
Chris Craikc3566d02013-02-04 16:16:33 -08001381
Chet Haasedd671592013-04-19 14:54:34 -07001382 virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
1383 bool useQuickReject) {
Chris Craikc3566d02013-02-04 16:16:33 -08001384 if (mDisplayList && mDisplayList->isRenderable()) {
Chris Craikff785832013-03-08 13:12:16 -08001385 mDisplayList->defer(deferStruct, level + 1);
Chris Craikc3566d02013-02-04 16:16:33 -08001386 }
Chris Craikc3566d02013-02-04 16:16:33 -08001387 }
Chet Haasedd671592013-04-19 14:54:34 -07001388 virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
1389 bool useQuickReject) {
Chris Craikff785832013-03-08 13:12:16 -08001390 if (mDisplayList && mDisplayList->isRenderable()) {
1391 mDisplayList->replay(replayStruct, level + 1);
1392 }
1393 }
Chris Craik2af46352012-11-26 18:30:17 -08001394
Chris Craika08f95c2013-03-15 17:24:33 -07001395 // NOT USED since replay() is overridden
Chris Craik527a3aa2013-03-04 10:19:31 -08001396 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craika08f95c2013-03-15 17:24:33 -07001397 return DrawGlInfo::kStatusDone;
1398 }
Chris Craikff785832013-03-08 13:12:16 -08001399
1400 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001401 OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags);
Chris Craikff785832013-03-08 13:12:16 -08001402 if (mDisplayList && (logFlags & kOpLogFlag_Recurse)) {
Chris Craik2af46352012-11-26 18:30:17 -08001403 mDisplayList->output(level + 1);
1404 }
1405 }
1406
1407 virtual const char* name() { return "DrawDisplayList"; }
1408
1409private:
1410 DisplayList* mDisplayList;
1411 int mFlags;
1412};
1413
1414class DrawLayerOp : public DrawOp {
1415public:
Chris Craika08f95c2013-03-15 17:24:33 -07001416 DrawLayerOp(Layer* layer, float x, float y)
1417 : DrawOp(0), mLayer(layer), mX(x), mY(y) {}
Chris Craik2af46352012-11-26 18:30:17 -08001418
Chris Craik527a3aa2013-03-04 10:19:31 -08001419 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Chris Craika08f95c2013-03-15 17:24:33 -07001420 return renderer.drawLayer(mLayer, mX, mY);
Chris Craik2af46352012-11-26 18:30:17 -08001421 }
1422
Chris Craikff785832013-03-08 13:12:16 -08001423 virtual void output(int level, uint32_t logFlags) {
Chris Craik2af46352012-11-26 18:30:17 -08001424 OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY);
1425 }
1426
1427 virtual const char* name() { return "DrawLayer"; }
1428
1429private:
1430 Layer* mLayer;
1431 float mX;
1432 float mY;
1433};
1434
1435}; // namespace uirenderer
1436}; // namespace android
1437
1438#endif // ANDROID_HWUI_DISPLAY_OPERATION_H