blob: 6425b43dc015d86aec2efbd4651d0aa28a1456e6 [file] [log] [blame]
Chris Craik2af46352012-11-26 18:30:17 -08001/*
2 * Copyright (C) 2012 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_DISPLAY_OPERATION_H
18#define ANDROID_HWUI_DISPLAY_OPERATION_H
19
20#include <SkXfermode.h>
21
22#include "OpenGLRenderer.h"
23#include "DisplayListRenderer.h"
24#include "utils/LinearAllocator.h"
25
26#define CRASH() do { \
27 *(int *)(uintptr_t)0xbbadbeef = 0; \
28 ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
29} while(false)
30
31#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
32#define MATRIX_ARGS(m) \
33 m->get(0), m->get(1), m->get(2), \
34 m->get(3), m->get(4), m->get(5), \
35 m->get(6), m->get(7), m->get(8)
36#define RECT_STRING "%.2f %.2f %.2f %.2f"
37#define RECT_ARGS(r) \
38 r.left, r.top, r.right, r.bottom
39
40// Use OP_LOG for logging with arglist, OP_LOGS if just printing char*
41#define OP_LOGS(s) OP_LOG("%s", s)
Chris Craik3dc553b2013-02-04 12:45:13 -080042#define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ )
Chris Craik2af46352012-11-26 18:30:17 -080043
44
45namespace android {
46namespace uirenderer {
47
48/**
49 * Structure for storing canvas operations when they are recorded into a DisplayList, so that they
50 * may be replayed to an OpenGLRenderer.
51 *
52 * To avoid individual memory allocations, DisplayListOps may only be allocated into a
53 * LinearAllocator's managed memory buffers. Each pointer held by a DisplayListOp is either a
54 * pointer into memory also allocated in the LinearAllocator (mostly for text and float buffers) or
55 * references a externally refcounted object (Sk... and Skia... objects). ~DisplayListOp() is
56 * never called as LinearAllocators are simply discarded, so no memory management should be done in
57 * this class.
58 */
59class DisplayListOp {
60public:
61 // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted.
62 // standard new() intentionally not implemented, and delete/deconstructor should never be used.
63 virtual ~DisplayListOp() { CRASH(); }
64 static void operator delete(void* ptr) { CRASH(); }
65 /** static void* operator new(size_t size); PURPOSELY OMITTED **/
66 static void* operator new(size_t size, LinearAllocator& allocator) {
67 return allocator.alloc(size);
68 }
69
70 enum OpLogFlag {
71 kOpLogFlag_Recurse = 0x1,
72 kOpLogFlag_JSON = 0x2 // TODO: add?
73 };
74
75 //TODO: for draw batching, DrawOps should override a virtual sub-method, with
76 // DrawOps::apply deferring operations to a different list if possible
77 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
78 uint32_t level, bool caching, int multipliedAlpha) = 0;
79
80 virtual void output(int level, uint32_t flags = 0) = 0;
81
82 // NOTE: it would be nice to declare constants and overriding the implementation in each op to
83 // point at the constants, but that seems to require a .cpp file
84 virtual const char* name() = 0;
85};
86
87class StateOp : public DisplayListOp {
88public:
89 StateOp() {};
90
91 virtual ~StateOp() {}
92
93 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
94 uint32_t level, bool caching, int multipliedAlpha) {
95 applyState(renderer, saveCount);
96 return DrawGlInfo::kStatusDone;
97 }
98
99 virtual void applyState(OpenGLRenderer& renderer, int saveCount) = 0;
100};
101
102class DrawOp : public DisplayListOp {
103public:
104 DrawOp(SkPaint* paint)
105 : mPaint(paint), mQuickRejected(false) {}
106
107 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
108 uint32_t level, bool caching, int multipliedAlpha) {
109 if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) {
110 return DrawGlInfo::kStatusDone;
111 }
112
113 return applyDraw(renderer, dirty, level, caching, multipliedAlpha);
114 }
115
116 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
117 bool caching, int multipliedAlpha) = 0;
118
119 // returns true if bounds exist
120 virtual bool getLocalBounds(Rect& localBounds) { return false; }
121
122 // TODO: better refine localbounds usage
123 void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; }
124 bool getQuickRejected() { return mQuickRejected; }
125
126protected:
127 SkPaint* getPaint(OpenGLRenderer& renderer) {
128 return renderer.filterPaint(mPaint);
129 }
130
131 SkPaint* mPaint; // should be accessed via getPaint() when applying
132 bool mQuickRejected;
133};
134
135class DrawBoundedOp : public DrawOp {
136public:
137 DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
138 : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
139
140 // default constructor for area, to be overridden in child constructor body
141 DrawBoundedOp(SkPaint* paint)
142 : DrawOp(paint) {}
143
144 bool getLocalBounds(Rect& localBounds) {
145 localBounds.set(mLocalBounds);
146 return true;
147 }
148
149protected:
150 Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint
151};
152
153///////////////////////////////////////////////////////////////////////////////
154// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do
155// not directly draw or alter output
156///////////////////////////////////////////////////////////////////////////////
157
158class SaveOp : public StateOp {
159public:
160 SaveOp(int flags)
161 : mFlags(flags) {}
162
163 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
164 renderer.save(mFlags);
165 }
166
167 virtual void output(int level, uint32_t flags = 0) {
168 OP_LOG("Save flags %x", mFlags);
169 }
170
171 virtual const char* name() { return "Save"; }
172
173private:
174 int mFlags;
175};
176
177class RestoreToCountOp : public StateOp {
178public:
179 RestoreToCountOp(int count)
180 : mCount(count) {}
181
182 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
183 renderer.restoreToCount(saveCount + mCount);
184
185 }
186
187 virtual void output(int level, uint32_t flags = 0) {
188 OP_LOG("Restore to count %d", mCount);
189 }
190
191 virtual const char* name() { return "RestoreToCount"; }
192
193private:
194 int mCount;
195};
196
197class SaveLayerOp : public StateOp {
198public:
199 SaveLayerOp(float left, float top, float right, float bottom, SkPaint* paint, int flags)
200 : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {}
201
202 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
203 SkPaint* paint = renderer.filterPaint(mPaint);
204 renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, paint, mFlags);
205 }
206
207 virtual void output(int level, uint32_t flags = 0) {
208 OP_LOG("SaveLayer of area " RECT_STRING, RECT_ARGS(mArea));
209 }
210
211 virtual const char* name() { return "SaveLayer"; }
212
213private:
214 Rect mArea;
215 SkPaint* mPaint;
216 int mFlags;
217};
218
219class SaveLayerAlphaOp : public StateOp {
220public:
221 SaveLayerAlphaOp(float left, float top, float right, float bottom, int alpha, int flags)
222 : mArea(left, top, right, bottom), mAlpha(alpha), mFlags(flags) {}
223
224 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
225 renderer.saveLayerAlpha(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mFlags);
226 }
227
228 virtual void output(int level, uint32_t flags = 0) {
229 OP_LOG("SaveLayerAlpha of area " RECT_STRING, RECT_ARGS(mArea));
230 }
231
232 virtual const char* name() { return "SaveLayerAlpha"; }
233private:
234 Rect mArea;
235 int mAlpha;
236 int mFlags;
237};
238
239class TranslateOp : public StateOp {
240public:
241 TranslateOp(float dx, float dy)
242 : mDx(dx), mDy(dy) {}
243
244 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
245 renderer.translate(mDx, mDy);
246 }
247
248 virtual void output(int level, uint32_t flags = 0) {
249 OP_LOG("Translate by %f %f", mDx, mDy);
250 }
251
252 virtual const char* name() { return "Translate"; }
253
254private:
255 float mDx;
256 float mDy;
257};
258
259class RotateOp : public StateOp {
260public:
261 RotateOp(float degrees)
262 : mDegrees(degrees) {}
263
264 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
265 renderer.rotate(mDegrees);
266 }
267
268 virtual void output(int level, uint32_t flags = 0) {
269 OP_LOG("Rotate by %f degrees", mDegrees);
270 }
271
272 virtual const char* name() { return "Rotate"; }
273
274private:
275 float mDegrees;
276};
277
278class ScaleOp : public StateOp {
279public:
280 ScaleOp(float sx, float sy)
281 : mSx(sx), mSy(sy) {}
282
283 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
284 renderer.scale(mSx, mSy);
285 }
286
287 virtual void output(int level, uint32_t flags = 0) {
288 OP_LOG("Scale by %f %f", mSx, mSy);
289 }
290
291 virtual const char* name() { return "Scale"; }
292
293private:
294 float mSx;
295 float mSy;
296};
297
298class SkewOp : public StateOp {
299public:
300 SkewOp(float sx, float sy)
301 : mSx(sx), mSy(sy) {}
302
303 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
304 renderer.skew(mSx, mSy);
305 }
306
307 virtual void output(int level, uint32_t flags = 0) {
308 OP_LOG("Skew by %f %f", mSx, mSy);
309 }
310
311 virtual const char* name() { return "Skew"; }
312
313private:
314 float mSx;
315 float mSy;
316};
317
318class SetMatrixOp : public StateOp {
319public:
320 SetMatrixOp(SkMatrix* matrix)
321 : mMatrix(matrix) {}
322
323 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
324 renderer.setMatrix(mMatrix);
325 }
326
327 virtual void output(int level, uint32_t flags = 0) {
328 OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
329 }
330
331 virtual const char* name() { return "SetMatrix"; }
332
333private:
334 SkMatrix* mMatrix;
335};
336
337class ConcatMatrixOp : public StateOp {
338public:
339 ConcatMatrixOp(SkMatrix* matrix)
340 : mMatrix(matrix) {}
341
342 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
343 renderer.concatMatrix(mMatrix);
344 }
345
346 virtual void output(int level, uint32_t flags = 0) {
347 OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
348 }
349
350 virtual const char* name() { return "ConcatMatrix"; }
351
352private:
353 SkMatrix* mMatrix;
354};
355
356class ClipRectOp : public StateOp {
357public:
358 ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op)
359 : mArea(left, top, right, bottom), mOp(op) {}
360
361 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
362 renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp);
363 }
364
365 virtual void output(int level, uint32_t flags = 0) {
366 OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea));
367 }
368
369 virtual const char* name() { return "ClipRect"; }
370
371private:
372 Rect mArea;
373 SkRegion::Op mOp;
374};
375
376class ClipPathOp : public StateOp {
377public:
378 ClipPathOp(SkPath* path, SkRegion::Op op)
379 : mPath(path), mOp(op) {}
380
381 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
382 renderer.clipPath(mPath, mOp);
383 }
384
385 virtual void output(int level, uint32_t flags = 0) {
386 SkRect bounds = mPath->getBounds();
387 OP_LOG("ClipPath bounds " RECT_STRING,
388 bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
389 }
390
391 virtual const char* name() { return "ClipPath"; }
392
393private:
394 SkPath* mPath;
395 SkRegion::Op mOp;
396};
397
398class ClipRegionOp : public StateOp {
399public:
400 ClipRegionOp(SkRegion* region, SkRegion::Op op)
401 : mRegion(region), mOp(op) {}
402
403 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
404 renderer.clipRegion(mRegion, mOp);
405 }
406
407 virtual void output(int level, uint32_t flags = 0) {
408 SkIRect bounds = mRegion->getBounds();
409 OP_LOG("ClipRegion bounds %d %d %d %d",
410 bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
411 }
412
413 virtual const char* name() { return "ClipRegion"; }
414
415private:
416 SkRegion* mRegion;
417 SkRegion::Op mOp;
418};
419
420class ResetShaderOp : public StateOp {
421public:
422 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
423 renderer.resetShader();
424 }
425
426 virtual void output(int level, uint32_t flags = 0) {
427 OP_LOGS("ResetShader");
428 }
429
430 virtual const char* name() { return "ResetShader"; }
431};
432
433class SetupShaderOp : public StateOp {
434public:
435 SetupShaderOp(SkiaShader* shader)
436 : mShader(shader) {}
437 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
438 renderer.setupShader(mShader);
439 }
440
441 virtual void output(int level, uint32_t flags = 0) {
442 OP_LOG("SetupShader, shader %p", mShader);
443 }
444
445 virtual const char* name() { return "SetupShader"; }
446
447private:
448 SkiaShader* mShader;
449};
450
451class ResetColorFilterOp : public StateOp {
452public:
453 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
454 renderer.resetColorFilter();
455 }
456
457 virtual void output(int level, uint32_t flags = 0) {
458 OP_LOGS("ResetColorFilter");
459 }
460
461 virtual const char* name() { return "ResetColorFilter"; }
462};
463
464class SetupColorFilterOp : public StateOp {
465public:
466 SetupColorFilterOp(SkiaColorFilter* colorFilter)
467 : mColorFilter(colorFilter) {}
468
469 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
470 renderer.setupColorFilter(mColorFilter);
471 }
472
473 virtual void output(int level, uint32_t flags = 0) {
474 OP_LOG("SetupColorFilter, filter %p", mColorFilter);
475 }
476
477 virtual const char* name() { return "SetupColorFilter"; }
478
479private:
480 SkiaColorFilter* mColorFilter;
481};
482
483class ResetShadowOp : public StateOp {
484public:
485 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
486 renderer.resetShadow();
487 }
488
489 virtual void output(int level, uint32_t flags = 0) {
490 OP_LOGS("ResetShadow");
491 }
492
493 virtual const char* name() { return "ResetShadow"; }
494};
495
496class SetupShadowOp : public StateOp {
497public:
498 SetupShadowOp(float radius, float dx, float dy, int color)
499 : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {}
500
501 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
502 renderer.setupShadow(mRadius, mDx, mDy, mColor);
503 }
504
505 virtual void output(int level, uint32_t flags = 0) {
506 OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor);
507 }
508
509 virtual const char* name() { return "SetupShadow"; }
510
511private:
512 float mRadius;
513 float mDx;
514 float mDy;
515 int mColor;
516};
517
518class ResetPaintFilterOp : public StateOp {
519public:
520 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
521 renderer.resetPaintFilter();
522 }
523
524 virtual void output(int level, uint32_t flags = 0) {
525 OP_LOGS("ResetPaintFilter");
526 }
527
528 virtual const char* name() { return "ResetPaintFilter"; }
529};
530
531class SetupPaintFilterOp : public StateOp {
532public:
533 SetupPaintFilterOp(int clearBits, int setBits)
534 : mClearBits(clearBits), mSetBits(setBits) {}
535
536 virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
537 renderer.setupPaintFilter(mClearBits, mSetBits);
538 }
539
540 virtual void output(int level, uint32_t flags = 0) {
541 OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits);
542 }
543
544 virtual const char* name() { return "SetupPaintFilter"; }
545
546private:
547 int mClearBits;
548 int mSetBits;
549};
550
551
552///////////////////////////////////////////////////////////////////////////////
553// DRAW OPERATIONS - these are operations that can draw to the canvas's device
554///////////////////////////////////////////////////////////////////////////////
555
556class DrawBitmapOp : public DrawBoundedOp {
557public:
558 DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
559 : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(),
560 paint),
561 mBitmap(bitmap) {}
562
563 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
564 bool caching, int multipliedAlpha) {
565 SkPaint* paint = getPaint(renderer);
566 int oldAlpha = -1;
567 if (caching && multipliedAlpha < 255) {
568 oldAlpha = paint->getAlpha();
569 paint->setAlpha(multipliedAlpha);
570 }
571 status_t ret = renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, paint);
572 if (oldAlpha >= 0) {
573 paint->setAlpha(oldAlpha);
574 }
575 return ret;
576 }
577
578 virtual void output(int level, uint32_t flags) {
579 OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top);
580 }
581
582 virtual const char* name() { return "DrawBitmap"; }
583
584protected:
585 SkBitmap* mBitmap;
586};
587
588class DrawBitmapMatrixOp : public DrawBoundedOp {
589public:
590 DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint)
591 : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
592 mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
593 const mat4 transform(*matrix);
594 transform.mapRect(mLocalBounds);
595 }
596
597 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
598 bool caching, int multipliedAlpha) {
599 return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer));
600 }
601
602 virtual void output(int level, uint32_t flags) {
603 OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix));
604 }
605
606 virtual const char* name() { return "DrawBitmap"; }
607
608private:
609 SkBitmap* mBitmap;
610 SkMatrix* mMatrix;
611};
612
613class DrawBitmapRectOp : public DrawBoundedOp {
614public:
615 DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom,
616 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint)
617 : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
618 mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
619
620 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
621 bool caching, int multipliedAlpha) {
622 return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
623 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
624 getPaint(renderer));
625 }
626
627 virtual void output(int level, uint32_t flags) {
628 OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING,
629 mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds));
630 }
631
632 virtual const char* name() { return "DrawBitmapRect"; }
633
634private:
635 SkBitmap* mBitmap;
636 Rect mSrc;
637};
638
639class DrawBitmapDataOp : public DrawBitmapOp {
640public:
641 DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
642 : DrawBitmapOp(bitmap, left, top, paint) {}
643
644 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
645 bool caching, int multipliedAlpha) {
646 return renderer.drawBitmapData(mBitmap, mLocalBounds.left,
647 mLocalBounds.top, getPaint(renderer));
648 }
649
650 virtual void output(int level, uint32_t flags) {
651 OP_LOG("Draw bitmap %p", mBitmap);
652 }
653
654 virtual const char* name() { return "DrawBitmapData"; }
655};
656
657class DrawBitmapMeshOp : public DrawOp {
658public:
659 DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight,
660 float* vertices, int* colors, SkPaint* paint)
661 : DrawOp(paint), mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
662 mVertices(vertices), mColors(colors) {}
663
664 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
665 bool caching, int multipliedAlpha) {
666 return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
667 mVertices, mColors, getPaint(renderer));
668 }
669
670 virtual void output(int level, uint32_t flags) {
671 OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight);
672 }
673
674 virtual const char* name() { return "DrawBitmapMesh"; }
675
676private:
677 SkBitmap* mBitmap;
678 int mMeshWidth;
679 int mMeshHeight;
680 float* mVertices;
681 int* mColors;
682};
683
684class DrawPatchOp : public DrawBoundedOp {
685public:
686 DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs,
687 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
688 int8_t numColors, float left, float top, float right, float bottom,
689 int alpha, SkXfermode::Mode mode)
690 : DrawBoundedOp(left, top, right, bottom, 0),
691 mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs),
692 mColors(colors), mxDivsCount(width), myDivsCount(height),
693 mNumColors(numColors), mAlpha(alpha), mMode(mode) {};
694
695 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
696 bool caching, int multipliedAlpha) {
697 // NOTE: not calling the virtual method, which takes a paint
698 return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors,
699 mxDivsCount, myDivsCount, mNumColors,
700 mLocalBounds.left, mLocalBounds.top,
701 mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode);
702 }
703
704 virtual void output(int level, uint32_t flags) {
705 OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds));
706 }
707
708 virtual const char* name() { return "DrawPatch"; }
709
710private:
711 SkBitmap* mBitmap;
712 const int32_t* mxDivs;
713 const int32_t* myDivs;
714 const uint32_t* mColors;
715 uint32_t mxDivsCount;
716 uint32_t myDivsCount;
717 int8_t mNumColors;
718 int mAlpha;
719 SkXfermode::Mode mMode;
720};
721
722class DrawColorOp : public DrawOp {
723public:
724 DrawColorOp(int color, SkXfermode::Mode mode)
725 : DrawOp(0), mColor(color), mMode(mode) {};
726
727 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
728 bool caching, int multipliedAlpha) {
729 return renderer.drawColor(mColor, mMode);
730 }
731
732 virtual void output(int level, uint32_t flags) {
733 OP_LOG("Draw color %#x, mode %d", mColor, mMode);
734 }
735
736 virtual const char* name() { return "DrawColor"; }
737
738private:
739 int mColor;
740 SkXfermode::Mode mMode;
741};
742
743class DrawStrokableOp : public DrawBoundedOp {
744public:
745 DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
746 : DrawBoundedOp(left, top, right, bottom, paint) {};
747
748 bool getLocalBounds(Rect& localBounds) {
749 if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
750 float outset = mPaint->getStrokeWidth() * 0.5f;
751 localBounds.set(mLocalBounds.left - outset, mLocalBounds.top - outset,
752 mLocalBounds.right + outset, mLocalBounds.bottom + outset);
753 } else {
754 localBounds.set(mLocalBounds);
755 }
756 return true;
757 }
758};
759
760class DrawRectOp : public DrawStrokableOp {
761public:
762 DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint)
763 : DrawStrokableOp(left, top, right, bottom, paint) {}
764
765 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
766 bool caching, int multipliedAlpha) {
767 return renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
768 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
769 }
770
771 virtual void output(int level, uint32_t flags) {
772 OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds));
773 }
774
775 virtual const char* name() { return "DrawRect"; }
776};
777
778class DrawRectsOp : public DrawOp {
779public:
780 DrawRectsOp(const float* rects, int count, SkPaint* paint)
781 : DrawOp(paint), mRects(rects), mCount(count) {}
782
783 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
784 bool caching, int multipliedAlpha) {
785 return renderer.drawRects(mRects, mCount, getPaint(renderer));
786 }
787
788 virtual void output(int level, uint32_t flags) {
789 OP_LOG("Draw Rects count %d", mCount);
790 }
791
792 virtual const char* name() { return "DrawRects"; }
793
794private:
795 const float* mRects;
796 int mCount;
797};
798
799class DrawRoundRectOp : public DrawStrokableOp {
800public:
801 DrawRoundRectOp(float left, float top, float right, float bottom,
802 float rx, float ry, SkPaint* paint)
803 : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
804
805 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
806 bool caching, int multipliedAlpha) {
807 return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
808 mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer));
809 }
810
811 virtual void output(int level, uint32_t flags) {
812 OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy);
813 }
814
815 virtual const char* name() { return "DrawRoundRect"; }
816
817private:
818 float mRx;
819 float mRy;
820};
821
822class DrawCircleOp : public DrawStrokableOp {
823public:
824 DrawCircleOp(float x, float y, float radius, SkPaint* paint)
825 : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
826 mX(x), mY(y), mRadius(radius) {}
827
828 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
829 bool caching, int multipliedAlpha) {
830 return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer));
831 }
832
833 virtual void output(int level, uint32_t flags) {
834 OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius);
835 }
836
837 virtual const char* name() { return "DrawCircle"; }
838
839private:
840 float mX;
841 float mY;
842 float mRadius;
843};
844
845class DrawOvalOp : public DrawStrokableOp {
846public:
847 DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint)
848 : DrawStrokableOp(left, top, right, bottom, paint) {}
849
850 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
851 bool caching, int multipliedAlpha) {
852 return renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
853 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
854 }
855
856 virtual void output(int level, uint32_t flags) {
857 OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds));
858 }
859
860 virtual const char* name() { return "DrawOval"; }
861};
862
863class DrawArcOp : public DrawStrokableOp {
864public:
865 DrawArcOp(float left, float top, float right, float bottom,
866 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint)
867 : DrawStrokableOp(left, top, right, bottom, paint),
868 mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
869
870 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
871 bool caching, int multipliedAlpha) {
872 return renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
873 mLocalBounds.right, mLocalBounds.bottom,
874 mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer));
875 }
876
877 virtual void output(int level, uint32_t flags) {
878 OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d",
879 RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter);
880 }
881
882 virtual const char* name() { return "DrawArc"; }
883
884private:
885 float mStartAngle;
886 float mSweepAngle;
887 bool mUseCenter;
888};
889
890class DrawPathOp : public DrawBoundedOp {
891public:
892 DrawPathOp(SkPath* path, SkPaint* paint)
893 : DrawBoundedOp(paint), mPath(path) {
894 float left, top, offset;
895 uint32_t width, height;
896 computePathBounds(path, paint, left, top, offset, width, height);
897 left -= offset;
898 top -= offset;
899 mLocalBounds.set(left, top, left + width, top + height);
900 }
901
902 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
903 bool caching, int multipliedAlpha) {
904 return renderer.drawPath(mPath, getPaint(renderer));
905 }
906
907 virtual void output(int level, uint32_t flags) {
908 OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds));
909 }
910
911 virtual const char* name() { return "DrawPath"; }
912
913private:
914 SkPath* mPath;
915};
916
917class DrawLinesOp : public DrawOp {
918public:
919 DrawLinesOp(float* points, int count, SkPaint* paint)
920 : DrawOp(paint), mPoints(points), mCount(count) {
921 /* TODO: inherit from DrawBoundedOp and calculate localbounds something like:
922 for (int i = 0; i < count; i += 2) {
923 mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
924 mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]);
925 mLocalBounds.top = fminf(mLocalBounds.top, points[i+1]);
926 mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i+1]);
927 }
928 */
929 }
930
931 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
932 bool caching, int multipliedAlpha) {
933 return renderer.drawLines(mPoints, mCount, getPaint(renderer));
934 }
935
936 virtual void output(int level, uint32_t flags) {
937 OP_LOG("Draw Lines count %d", mCount);
938 }
939
940 virtual const char* name() { return "DrawLines"; }
941
942protected:
943 float* mPoints;
944 int mCount;
945};
946
947class DrawPointsOp : public DrawLinesOp {
948public:
949 DrawPointsOp(float* points, int count, SkPaint* paint)
950 : DrawLinesOp(points, count, paint) {}
951
952 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
953 bool caching, int multipliedAlpha) {
954 return renderer.drawPoints(mPoints, mCount, getPaint(renderer));
955 }
956
957 virtual void output(int level, uint32_t flags) {
958 OP_LOG("Draw Points count %d", mCount);
959 }
960
961 virtual const char* name() { return "DrawPoints"; }
962};
963
964class DrawSomeTextOp : public DrawOp {
965public:
966 DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint)
967 : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
968
969 virtual void output(int level, uint32_t flags) {
970 OP_LOG("Draw some text, %d bytes", mBytesCount);
971 }
972protected:
973 const char* mText;
974 int mBytesCount;
975 int mCount;
976};
977
978class DrawTextOnPathOp : public DrawSomeTextOp {
979public:
980 DrawTextOnPathOp(const char* text, int bytesCount, int count,
981 SkPath* path, float hOffset, float vOffset, SkPaint* paint)
982 : DrawSomeTextOp(text, bytesCount, count, paint),
983 mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
984 /* TODO: inherit from DrawBounded and init mLocalBounds */
985 }
986
987 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
988 bool caching, int multipliedAlpha) {
989 return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
990 mHOffset, mVOffset, getPaint(renderer));
991 }
992
993 virtual const char* name() { return "DrawTextOnPath"; }
994
995private:
996 SkPath* mPath;
997 float mHOffset;
998 float mVOffset;
999};
1000
1001class DrawPosTextOp : public DrawSomeTextOp {
1002public:
1003 DrawPosTextOp(const char* text, int bytesCount, int count,
1004 const float* positions, SkPaint* paint)
1005 : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) {
1006 /* TODO: inherit from DrawBounded and init mLocalBounds */
1007 }
1008
1009 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
1010 bool caching, int multipliedAlpha) {
1011 return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer));
1012 }
1013
1014 virtual const char* name() { return "DrawPosText"; }
1015
1016private:
1017 const float* mPositions;
1018};
1019
1020class DrawTextOp : public DrawBoundedOp {
1021public:
1022 DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
1023 const float* positions, SkPaint* paint, float length)
1024 : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count),
1025 mX(x), mY(y), mPositions(positions), mLength(length) {
1026 SkPaint::FontMetrics metrics;
1027 paint->getFontMetrics(&metrics, 0.0f);
1028 mLocalBounds.set(mX, mY + metrics.fTop, mX + length, mY + metrics.fBottom);
1029 }
1030
1031 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
1032 bool caching, int multipliedAlpha) {
1033 return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
1034 mPositions, getPaint(renderer), mLength);
1035 }
1036
1037 virtual void output(int level, uint32_t flags) {
1038 OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount);
1039 }
1040
1041 virtual const char* name() { return "DrawText"; }
1042
1043private:
1044 const char* mText;
1045 int mBytesCount;
1046 int mCount;
1047 float mX;
1048 float mY;
1049 const float* mPositions;
1050 float mLength;
1051};
1052
1053///////////////////////////////////////////////////////////////////////////////
1054// SPECIAL DRAW OPERATIONS
1055///////////////////////////////////////////////////////////////////////////////
1056
1057class DrawFunctorOp : public DrawOp {
1058public:
1059 DrawFunctorOp(Functor* functor)
1060 : DrawOp(0), mFunctor(functor) {}
1061
1062 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
1063 bool caching, int multipliedAlpha) {
1064 renderer.startMark("GL functor");
1065 status_t ret = renderer.callDrawGLFunction(mFunctor, dirty);
1066 renderer.endMark();
1067 return ret;
1068 }
1069
1070 virtual void output(int level, uint32_t flags) {
1071 OP_LOG("Draw Functor %p", mFunctor);
1072 }
1073
1074 virtual const char* name() { return "DrawFunctor"; }
1075
1076private:
1077 Functor* mFunctor;
1078};
1079
1080class DrawDisplayListOp : public DrawOp {
1081public:
1082 DrawDisplayListOp(DisplayList* displayList, int flags)
1083 : DrawOp(0), mDisplayList(displayList), mFlags(flags) {}
1084 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
1085 bool caching, int multipliedAlpha) {
1086 return renderer.drawDisplayList(mDisplayList, dirty, mFlags, level + 1);
1087 }
1088
1089 virtual void output(int level, uint32_t flags) {
1090 OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags);
1091 if (mDisplayList && (flags & kOpLogFlag_Recurse)) {
1092 mDisplayList->output(level + 1);
1093 }
1094 }
1095
1096 virtual const char* name() { return "DrawDisplayList"; }
1097
1098private:
1099 DisplayList* mDisplayList;
1100 int mFlags;
1101};
1102
1103class DrawLayerOp : public DrawOp {
1104public:
1105 DrawLayerOp(Layer* layer, float x, float y, SkPaint* paint)
1106 : DrawOp(paint), mLayer(layer), mX(x), mY(y) {}
1107
1108 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
1109 bool caching, int multipliedAlpha) {
1110 int oldAlpha = -1;
1111
1112 if (caching && multipliedAlpha < 255) {
1113 oldAlpha = mLayer->getAlpha();
1114 mLayer->setAlpha(multipliedAlpha);
1115 }
1116 status_t ret = renderer.drawLayer(mLayer, mX, mY, getPaint(renderer));
1117 if (oldAlpha >= 0) {
1118 mLayer->setAlpha(oldAlpha);
1119 }
1120 return ret;
1121 }
1122
1123 virtual void output(int level, uint32_t flags) {
1124 OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY);
1125 }
1126
1127 virtual const char* name() { return "DrawLayer"; }
1128
1129private:
1130 Layer* mLayer;
1131 float mX;
1132 float mY;
1133};
1134
1135}; // namespace uirenderer
1136}; // namespace android
1137
1138#endif // ANDROID_HWUI_DISPLAY_OPERATION_H