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