DisplayListOp.h revision 3dc553babe515fbf9bd042dd63a792e5de578ecd
1/*
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)
42#define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ )
43
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
1139