DisplayListRenderer.cpp revision 13631f3da855f200a151e7837ed9f6b079622b58
1/*
2 * Copyright (C) 2010 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#define LOG_TAG "OpenGLRenderer"
18
19
20#include "DisplayListLogBuffer.h"
21#include "DisplayListRenderer.h"
22#include "Caches.h"
23
24#include <utils/String8.h>
25
26namespace android {
27namespace uirenderer {
28
29
30///////////////////////////////////////////////////////////////////////////////
31// Display list
32///////////////////////////////////////////////////////////////////////////////
33
34const char* DisplayList::OP_NAMES[] = {
35    "Save",
36    "Restore",
37    "RestoreToCount",
38    "SaveLayer",
39    "SaveLayerAlpha",
40    "Translate",
41    "Rotate",
42    "Scale",
43    "Skew",
44    "SetMatrix",
45    "ConcatMatrix",
46    "ClipRect",
47    "DrawDisplayList",
48    "DrawLayer",
49    "DrawBitmap",
50    "DrawBitmapMatrix",
51    "DrawBitmapRect",
52    "DrawBitmapMesh",
53    "DrawPatch",
54    "DrawColor",
55    "DrawRect",
56    "DrawRoundRect",
57    "DrawCircle",
58    "DrawOval",
59    "DrawArc",
60    "DrawPath",
61    "DrawLines",
62    "DrawPoints",
63    "DrawText",
64    "DrawPosText",
65    "ResetShader",
66    "SetupShader",
67    "ResetColorFilter",
68    "SetupColorFilter",
69    "ResetShadow",
70    "SetupShadow",
71    "ResetPaintFilter",
72    "SetupPaintFilter",
73    "DrawGLFunction"
74};
75
76void DisplayList::outputLogBuffer(int fd) {
77    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
78    if (logBuffer.isEmpty()) {
79        return;
80    }
81
82    FILE *file = fdopen(fd, "a");
83
84    fprintf(file, "\nRecent DisplayList operations\n");
85    logBuffer.outputCommands(file, OP_NAMES);
86
87    String8 cachesLog;
88    Caches::getInstance().dumpMemoryUsage(cachesLog);
89    fprintf(file, "\nCaches:\n%s", cachesLog.string());
90    fprintf(file, "\n");
91
92    fflush(file);
93}
94
95DisplayList::DisplayList(const DisplayListRenderer& recorder) {
96    initFromDisplayListRenderer(recorder);
97}
98
99DisplayList::~DisplayList() {
100    clearResources();
101}
102
103void DisplayList::clearResources() {
104    sk_free((void*) mReader.base());
105
106    Caches& caches = Caches::getInstance();
107
108    for (size_t i = 0; i < mBitmapResources.size(); i++) {
109        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
110    }
111    mBitmapResources.clear();
112
113    for (size_t i = 0; i < mFilterResources.size(); i++) {
114        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
115    }
116    mFilterResources.clear();
117
118    for (size_t i = 0; i < mShaders.size(); i++) {
119        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
120        caches.resourceCache.destructor(mShaders.itemAt(i));
121    }
122    mShaders.clear();
123
124    for (size_t i = 0; i < mPaints.size(); i++) {
125        delete mPaints.itemAt(i);
126    }
127    mPaints.clear();
128
129    for (size_t i = 0; i < mPaths.size(); i++) {
130        SkPath* path = mPaths.itemAt(i);
131        caches.pathCache.remove(path);
132        delete path;
133    }
134    mPaths.clear();
135
136    for (size_t i = 0; i < mMatrices.size(); i++) {
137        delete mMatrices.itemAt(i);
138    }
139    mMatrices.clear();
140}
141
142void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
143    const SkWriter32& writer = recorder.writeStream();
144    init();
145
146    if (writer.size() == 0) {
147        return;
148    }
149
150    if (reusing) {
151        // re-using display list - clear out previous allocations
152        clearResources();
153    }
154
155    mSize = writer.size();
156    void* buffer = sk_malloc_throw(mSize);
157    writer.flatten(buffer);
158    mReader.setMemory(buffer, mSize);
159
160    Caches& caches = Caches::getInstance();
161
162    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
163    for (size_t i = 0; i < bitmapResources.size(); i++) {
164        SkBitmap* resource = bitmapResources.itemAt(i);
165        mBitmapResources.add(resource);
166        caches.resourceCache.incrementRefcount(resource);
167    }
168
169    const Vector<SkiaColorFilter*> &filterResources = recorder.getFilterResources();
170    for (size_t i = 0; i < filterResources.size(); i++) {
171        SkiaColorFilter* resource = filterResources.itemAt(i);
172        mFilterResources.add(resource);
173        caches.resourceCache.incrementRefcount(resource);
174    }
175
176    const Vector<SkiaShader*> &shaders = recorder.getShaders();
177    for (size_t i = 0; i < shaders.size(); i++) {
178        SkiaShader* resource = shaders.itemAt(i);
179        mShaders.add(resource);
180        caches.resourceCache.incrementRefcount(resource);
181    }
182
183    const Vector<SkPaint*> &paints = recorder.getPaints();
184    for (size_t i = 0; i < paints.size(); i++) {
185        mPaints.add(paints.itemAt(i));
186    }
187
188    const Vector<SkPath*> &paths = recorder.getPaths();
189    for (size_t i = 0; i < paths.size(); i++) {
190        mPaths.add(paths.itemAt(i));
191    }
192
193    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
194    for (size_t i = 0; i < matrices.size(); i++) {
195        mMatrices.add(matrices.itemAt(i));
196    }
197}
198
199void DisplayList::init() {
200    mSize = 0;
201    mIsRenderable = true;
202}
203
204size_t DisplayList::getSize() {
205    return mSize;
206}
207
208/**
209 * This function is a simplified version of replay(), where we simply retrieve and log the
210 * display list. This function should remain in sync with the replay() function.
211 */
212void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
213    TextContainer text;
214
215    uint32_t count = (level + 1) * 2;
216    char indent[count + 1];
217    for (uint32_t i = 0; i < count; i++) {
218        indent[i] = ' ';
219    }
220    indent[count] = '\0';
221    ALOGD("%sStart display list (%p, %s)", (char*) indent + 2, this, mName.string());
222
223    int saveCount = renderer.getSaveCount() - 1;
224
225    mReader.rewind();
226
227    while (!mReader.eof()) {
228        int op = mReader.readInt();
229
230        switch (op) {
231            case DrawGLFunction: {
232                Functor *functor = (Functor *) getInt();
233                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
234            }
235            break;
236            case Save: {
237                int rendererNum = getInt();
238                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
239            }
240            break;
241            case Restore: {
242                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
243            }
244            break;
245            case RestoreToCount: {
246                int restoreCount = saveCount + getInt();
247                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
248            }
249            break;
250            case SaveLayer: {
251                float f1 = getFloat();
252                float f2 = getFloat();
253                float f3 = getFloat();
254                float f4 = getFloat();
255                SkPaint* paint = getPaint(renderer);
256                int flags = getInt();
257                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
258                    OP_NAMES[op], f1, f2, f3, f4, paint, flags);
259            }
260            break;
261            case SaveLayerAlpha: {
262                float f1 = getFloat();
263                float f2 = getFloat();
264                float f3 = getFloat();
265                float f4 = getFloat();
266                int alpha = getInt();
267                int flags = getInt();
268                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
269                    OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
270            }
271            break;
272            case Translate: {
273                float f1 = getFloat();
274                float f2 = getFloat();
275                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
276            }
277            break;
278            case Rotate: {
279                float rotation = getFloat();
280                ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
281            }
282            break;
283            case Scale: {
284                float sx = getFloat();
285                float sy = getFloat();
286                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
287            }
288            break;
289            case Skew: {
290                float sx = getFloat();
291                float sy = getFloat();
292                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
293            }
294            break;
295            case SetMatrix: {
296                SkMatrix* matrix = getMatrix();
297                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
298            }
299            break;
300            case ConcatMatrix: {
301                SkMatrix* matrix = getMatrix();
302                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
303            }
304            break;
305            case ClipRect: {
306                float f1 = getFloat();
307                float f2 = getFloat();
308                float f3 = getFloat();
309                float f4 = getFloat();
310                int regionOp = getInt();
311                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
312                    f1, f2, f3, f4, regionOp);
313            }
314            break;
315            case DrawDisplayList: {
316                DisplayList* displayList = getDisplayList();
317                uint32_t width = getUInt();
318                uint32_t height = getUInt();
319                ALOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
320                    displayList, width, height, level + 1);
321                renderer.outputDisplayList(displayList, level + 1);
322            }
323            break;
324            case DrawLayer: {
325                Layer* layer = (Layer*) getInt();
326                float x = getFloat();
327                float y = getFloat();
328                SkPaint* paint = getPaint(renderer);
329                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
330                    layer, x, y, paint);
331            }
332            break;
333            case DrawBitmap: {
334                SkBitmap* bitmap = getBitmap();
335                float x = getFloat();
336                float y = getFloat();
337                SkPaint* paint = getPaint(renderer);
338                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
339                    bitmap, x, y, paint);
340            }
341            break;
342            case DrawBitmapMatrix: {
343                SkBitmap* bitmap = getBitmap();
344                SkMatrix* matrix = getMatrix();
345                SkPaint* paint = getPaint(renderer);
346                ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
347                    bitmap, matrix, paint);
348            }
349            break;
350            case DrawBitmapRect: {
351                SkBitmap* bitmap = getBitmap();
352                float f1 = getFloat();
353                float f2 = getFloat();
354                float f3 = getFloat();
355                float f4 = getFloat();
356                float f5 = getFloat();
357                float f6 = getFloat();
358                float f7 = getFloat();
359                float f8 = getFloat();
360                SkPaint* paint = getPaint(renderer);
361                ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
362                    (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
363            }
364            break;
365            case DrawBitmapMesh: {
366                int verticesCount = 0;
367                uint32_t colorsCount = 0;
368                SkBitmap* bitmap = getBitmap();
369                uint32_t meshWidth = getInt();
370                uint32_t meshHeight = getInt();
371                float* vertices = getFloats(verticesCount);
372                bool hasColors = getInt();
373                int* colors = hasColors ? getInts(colorsCount) : NULL;
374                SkPaint* paint = getPaint(renderer);
375                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
376            }
377            break;
378            case DrawPatch: {
379                int32_t* xDivs = NULL;
380                int32_t* yDivs = NULL;
381                uint32_t* colors = NULL;
382                uint32_t xDivsCount = 0;
383                uint32_t yDivsCount = 0;
384                int8_t numColors = 0;
385                SkBitmap* bitmap = getBitmap();
386                xDivs = getInts(xDivsCount);
387                yDivs = getInts(yDivsCount);
388                colors = getUInts(numColors);
389                float left = getFloat();
390                float top = getFloat();
391                float right = getFloat();
392                float bottom = getFloat();
393                SkPaint* paint = getPaint(renderer);
394                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
395                        left, top, right, bottom);
396            }
397            break;
398            case DrawColor: {
399                int color = getInt();
400                int xferMode = getInt();
401                ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
402            }
403            break;
404            case DrawRect: {
405                float f1 = getFloat();
406                float f2 = getFloat();
407                float f3 = getFloat();
408                float f4 = getFloat();
409                SkPaint* paint = getPaint(renderer);
410                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
411                    f1, f2, f3, f4, paint);
412            }
413            break;
414            case DrawRoundRect: {
415                float f1 = getFloat();
416                float f2 = getFloat();
417                float f3 = getFloat();
418                float f4 = getFloat();
419                float f5 = getFloat();
420                float f6 = getFloat();
421                SkPaint* paint = getPaint(renderer);
422                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
423                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
424            }
425            break;
426            case DrawCircle: {
427                float f1 = getFloat();
428                float f2 = getFloat();
429                float f3 = getFloat();
430                SkPaint* paint = getPaint(renderer);
431                ALOGD("%s%s %.2f, %.2f, %.2f, %p",
432                    (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
433            }
434            break;
435            case DrawOval: {
436                float f1 = getFloat();
437                float f2 = getFloat();
438                float f3 = getFloat();
439                float f4 = getFloat();
440                SkPaint* paint = getPaint(renderer);
441                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
442                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
443            }
444            break;
445            case DrawArc: {
446                float f1 = getFloat();
447                float f2 = getFloat();
448                float f3 = getFloat();
449                float f4 = getFloat();
450                float f5 = getFloat();
451                float f6 = getFloat();
452                int i1 = getInt();
453                SkPaint* paint = getPaint(renderer);
454                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
455                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
456            }
457            break;
458            case DrawPath: {
459                SkPath* path = getPath();
460                SkPaint* paint = getPaint(renderer);
461                ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
462            }
463            break;
464            case DrawLines: {
465                int count = 0;
466                float* points = getFloats(count);
467                SkPaint* paint = getPaint(renderer);
468                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
469            }
470            break;
471            case DrawPoints: {
472                int count = 0;
473                float* points = getFloats(count);
474                SkPaint* paint = getPaint(renderer);
475                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
476            }
477            break;
478            case DrawText: {
479                getText(&text);
480                int count = getInt();
481                float x = getFloat();
482                float y = getFloat();
483                SkPaint* paint = getPaint(renderer);
484                float length = getFloat();
485                ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
486                    text.text(), text.length(), count, x, y, paint, length);
487            }
488            break;
489            case DrawPosText: {
490                getText(&text);
491                int count = getInt();
492                int positionsCount = 0;
493                float* positions = getFloats(positionsCount);
494                SkPaint* paint = getPaint(renderer);
495                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
496                    text.text(), text.length(), count, paint);
497            }
498            case ResetShader: {
499                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
500            }
501            break;
502            case SetupShader: {
503                SkiaShader* shader = getShader();
504                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
505            }
506            break;
507            case ResetColorFilter: {
508                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
509            }
510            break;
511            case SetupColorFilter: {
512                SkiaColorFilter *colorFilter = getColorFilter();
513                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
514            }
515            break;
516            case ResetShadow: {
517                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
518            }
519            break;
520            case SetupShadow: {
521                float radius = getFloat();
522                float dx = getFloat();
523                float dy = getFloat();
524                int color = getInt();
525                ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
526                    radius, dx, dy, color);
527            }
528            break;
529            case ResetPaintFilter: {
530                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
531            }
532            break;
533            case SetupPaintFilter: {
534                int clearBits = getInt();
535                int setBits = getInt();
536                ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits);
537            }
538            break;
539            default:
540                ALOGD("Display List error: op not handled: %s%s",
541                    (char*) indent, OP_NAMES[op]);
542                break;
543        }
544    }
545
546    ALOGD("%sDone", (char*) indent + 2);
547}
548
549/**
550 * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
551 * in the output() function, since that function processes the same list of opcodes for the
552 * purposes of logging display list info for a given view.
553 */
554bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) {
555    bool needsInvalidate = false;
556    TextContainer text;
557    mReader.rewind();
558
559#if DEBUG_DISPLAY_LIST
560    uint32_t count = (level + 1) * 2;
561    char indent[count + 1];
562    for (uint32_t i = 0; i < count; i++) {
563        indent[i] = ' ';
564    }
565    indent[count] = '\0';
566    DISPLAY_LIST_LOGD("%sStart display list (%p, %s)", (char*) indent + 2, this, mName.string());
567#endif
568
569    renderer.startMark(mName.string());
570
571    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
572    int saveCount = renderer.getSaveCount() - 1;
573    while (!mReader.eof()) {
574        int op = mReader.readInt();
575        logBuffer.writeCommand(level, op);
576
577        switch (op) {
578            case DrawGLFunction: {
579                Functor *functor = (Functor *) getInt();
580                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
581                renderer.startMark("GL functor");
582                needsInvalidate |= renderer.callDrawGLFunction(functor, dirty);
583                renderer.endMark();
584            }
585            break;
586            case Save: {
587                int rendererNum = getInt();
588                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
589                renderer.save(rendererNum);
590            }
591            break;
592            case Restore: {
593                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
594                renderer.restore();
595            }
596            break;
597            case RestoreToCount: {
598                int restoreCount = saveCount + getInt();
599                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
600                renderer.restoreToCount(restoreCount);
601            }
602            break;
603            case SaveLayer: {
604                float f1 = getFloat();
605                float f2 = getFloat();
606                float f3 = getFloat();
607                float f4 = getFloat();
608                SkPaint* paint = getPaint(renderer);
609                int flags = getInt();
610                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
611                    OP_NAMES[op], f1, f2, f3, f4, paint, flags);
612                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
613            }
614            break;
615            case SaveLayerAlpha: {
616                float f1 = getFloat();
617                float f2 = getFloat();
618                float f3 = getFloat();
619                float f4 = getFloat();
620                int alpha = getInt();
621                int flags = getInt();
622                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
623                    OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
624                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
625            }
626            break;
627            case Translate: {
628                float f1 = getFloat();
629                float f2 = getFloat();
630                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
631                renderer.translate(f1, f2);
632            }
633            break;
634            case Rotate: {
635                float rotation = getFloat();
636                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
637                renderer.rotate(rotation);
638            }
639            break;
640            case Scale: {
641                float sx = getFloat();
642                float sy = getFloat();
643                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
644                renderer.scale(sx, sy);
645            }
646            break;
647            case Skew: {
648                float sx = getFloat();
649                float sy = getFloat();
650                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
651                renderer.skew(sx, sy);
652            }
653            break;
654            case SetMatrix: {
655                SkMatrix* matrix = getMatrix();
656                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
657                renderer.setMatrix(matrix);
658            }
659            break;
660            case ConcatMatrix: {
661                SkMatrix* matrix = getMatrix();
662                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
663                renderer.concatMatrix(matrix);
664            }
665            break;
666            case ClipRect: {
667                float f1 = getFloat();
668                float f2 = getFloat();
669                float f3 = getFloat();
670                float f4 = getFloat();
671                int regionOp = getInt();
672                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
673                    f1, f2, f3, f4, regionOp);
674                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
675            }
676            break;
677            case DrawDisplayList: {
678                DisplayList* displayList = getDisplayList();
679                uint32_t width = getUInt();
680                uint32_t height = getUInt();
681                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
682                    displayList, width, height, level + 1);
683                needsInvalidate |= renderer.drawDisplayList(displayList, width, height,
684                        dirty, level + 1);
685            }
686            break;
687            case DrawLayer: {
688                Layer* layer = (Layer*) getInt();
689                float x = getFloat();
690                float y = getFloat();
691                SkPaint* paint = getPaint(renderer);
692                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
693                    layer, x, y, paint);
694                renderer.drawLayer(layer, x, y, paint);
695            }
696            break;
697            case DrawBitmap: {
698                SkBitmap* bitmap = getBitmap();
699                float x = getFloat();
700                float y = getFloat();
701                SkPaint* paint = getPaint(renderer);
702                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
703                    bitmap, x, y, paint);
704                renderer.drawBitmap(bitmap, x, y, paint);
705            }
706            break;
707            case DrawBitmapMatrix: {
708                SkBitmap* bitmap = getBitmap();
709                SkMatrix* matrix = getMatrix();
710                SkPaint* paint = getPaint(renderer);
711                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
712                    bitmap, matrix, paint);
713                renderer.drawBitmap(bitmap, matrix, paint);
714            }
715            break;
716            case DrawBitmapRect: {
717                SkBitmap* bitmap = getBitmap();
718                float f1 = getFloat();
719                float f2 = getFloat();
720                float f3 = getFloat();
721                float f4 = getFloat();
722                float f5 = getFloat();
723                float f6 = getFloat();
724                float f7 = getFloat();
725                float f8 = getFloat();
726                SkPaint* paint = getPaint(renderer);
727                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
728                    (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
729                renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
730            }
731            break;
732            case DrawBitmapMesh: {
733                int verticesCount = 0;
734                uint32_t colorsCount = 0;
735
736                SkBitmap* bitmap = getBitmap();
737                uint32_t meshWidth = getInt();
738                uint32_t meshHeight = getInt();
739                float* vertices = getFloats(verticesCount);
740                bool hasColors = getInt();
741                int* colors = hasColors ? getInts(colorsCount) : NULL;
742                SkPaint* paint = getPaint(renderer);
743
744                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
745                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, paint);
746            }
747            break;
748            case DrawPatch: {
749                int32_t* xDivs = NULL;
750                int32_t* yDivs = NULL;
751                uint32_t* colors = NULL;
752                uint32_t xDivsCount = 0;
753                uint32_t yDivsCount = 0;
754                int8_t numColors = 0;
755
756                SkBitmap* bitmap = getBitmap();
757
758                xDivs = getInts(xDivsCount);
759                yDivs = getInts(yDivsCount);
760                colors = getUInts(numColors);
761
762                float left = getFloat();
763                float top = getFloat();
764                float right = getFloat();
765                float bottom = getFloat();
766                SkPaint* paint = getPaint(renderer);
767
768                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
769                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
770                        numColors, left, top, right, bottom, paint);
771            }
772            break;
773            case DrawColor: {
774                int color = getInt();
775                int xferMode = getInt();
776                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
777                renderer.drawColor(color, (SkXfermode::Mode) xferMode);
778            }
779            break;
780            case DrawRect: {
781                float f1 = getFloat();
782                float f2 = getFloat();
783                float f3 = getFloat();
784                float f4 = getFloat();
785                SkPaint* paint = getPaint(renderer);
786                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
787                    f1, f2, f3, f4, paint);
788                renderer.drawRect(f1, f2, f3, f4, paint);
789            }
790            break;
791            case DrawRoundRect: {
792                float f1 = getFloat();
793                float f2 = getFloat();
794                float f3 = getFloat();
795                float f4 = getFloat();
796                float f5 = getFloat();
797                float f6 = getFloat();
798                SkPaint* paint = getPaint(renderer);
799                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
800                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
801                renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
802            }
803            break;
804            case DrawCircle: {
805                float f1 = getFloat();
806                float f2 = getFloat();
807                float f3 = getFloat();
808                SkPaint* paint = getPaint(renderer);
809                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
810                    (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
811                renderer.drawCircle(f1, f2, f3, paint);
812            }
813            break;
814            case DrawOval: {
815                float f1 = getFloat();
816                float f2 = getFloat();
817                float f3 = getFloat();
818                float f4 = getFloat();
819                SkPaint* paint = getPaint(renderer);
820                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
821                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
822                renderer.drawOval(f1, f2, f3, f4, paint);
823            }
824            break;
825            case DrawArc: {
826                float f1 = getFloat();
827                float f2 = getFloat();
828                float f3 = getFloat();
829                float f4 = getFloat();
830                float f5 = getFloat();
831                float f6 = getFloat();
832                int i1 = getInt();
833                SkPaint* paint = getPaint(renderer);
834                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
835                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
836                renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
837            }
838            break;
839            case DrawPath: {
840                SkPath* path = getPath();
841                SkPaint* paint = getPaint(renderer);
842                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
843                renderer.drawPath(path, paint);
844            }
845            break;
846            case DrawLines: {
847                int count = 0;
848                float* points = getFloats(count);
849                SkPaint* paint = getPaint(renderer);
850                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
851                renderer.drawLines(points, count, paint);
852            }
853            break;
854            case DrawPoints: {
855                int count = 0;
856                float* points = getFloats(count);
857                SkPaint* paint = getPaint(renderer);
858                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
859                renderer.drawPoints(points, count, paint);
860            }
861            break;
862            case DrawText: {
863                getText(&text);
864                int count = getInt();
865                float x = getFloat();
866                float y = getFloat();
867                SkPaint* paint = getPaint(renderer);
868                float length = getFloat();
869                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
870                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
871                renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
872            }
873            break;
874            case DrawPosText: {
875                getText(&text);
876                int count = getInt();
877                int positionsCount = 0;
878                float* positions = getFloats(positionsCount);
879                SkPaint* paint = getPaint(renderer);
880                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
881                        OP_NAMES[op], text.text(), text.length(), count, paint);
882                renderer.drawPosText(text.text(), text.length(), count, positions, paint);
883            }
884            break;
885            case ResetShader: {
886                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
887                renderer.resetShader();
888            }
889            break;
890            case SetupShader: {
891                SkiaShader* shader = getShader();
892                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
893                renderer.setupShader(shader);
894            }
895            break;
896            case ResetColorFilter: {
897                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
898                renderer.resetColorFilter();
899            }
900            break;
901            case SetupColorFilter: {
902                SkiaColorFilter *colorFilter = getColorFilter();
903                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
904                renderer.setupColorFilter(colorFilter);
905            }
906            break;
907            case ResetShadow: {
908                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
909                renderer.resetShadow();
910            }
911            break;
912            case SetupShadow: {
913                float radius = getFloat();
914                float dx = getFloat();
915                float dy = getFloat();
916                int color = getInt();
917                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
918                    radius, dx, dy, color);
919                renderer.setupShadow(radius, dx, dy, color);
920            }
921            break;
922            case ResetPaintFilter: {
923                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
924                renderer.resetPaintFilter();
925            }
926            break;
927            case SetupPaintFilter: {
928                int clearBits = getInt();
929                int setBits = getInt();
930                DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
931                        clearBits, setBits);
932                renderer.setupPaintFilter(clearBits, setBits);
933            }
934            break;
935            default:
936                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
937                    (char*) indent, OP_NAMES[op]);
938                break;
939        }
940    }
941
942    renderer.endMark();
943
944    DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
945    return needsInvalidate;
946}
947
948///////////////////////////////////////////////////////////////////////////////
949// Base structure
950///////////////////////////////////////////////////////////////////////////////
951
952DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), mHasDrawOps(false) {
953}
954
955DisplayListRenderer::~DisplayListRenderer() {
956    reset();
957}
958
959void DisplayListRenderer::reset() {
960    mWriter.reset();
961
962    Caches& caches = Caches::getInstance();
963    for (size_t i = 0; i < mBitmapResources.size(); i++) {
964        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
965    }
966    mBitmapResources.clear();
967
968    for (size_t i = 0; i < mFilterResources.size(); i++) {
969        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
970    }
971    mFilterResources.clear();
972
973    for (size_t i = 0; i < mShaders.size(); i++) {
974        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
975    }
976    mShaders.clear();
977    mShaderMap.clear();
978
979    mPaints.clear();
980    mPaintMap.clear();
981
982    mPaths.clear();
983    mPathMap.clear();
984
985    mMatrices.clear();
986
987    mHasDrawOps = false;
988}
989
990///////////////////////////////////////////////////////////////////////////////
991// Operations
992///////////////////////////////////////////////////////////////////////////////
993
994DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
995    if (!displayList) {
996        displayList = new DisplayList(*this);
997    } else {
998        displayList->initFromDisplayListRenderer(*this, true);
999    }
1000    displayList->setRenderable(mHasDrawOps);
1001    return displayList;
1002}
1003
1004void DisplayListRenderer::setViewport(int width, int height) {
1005    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
1006
1007    mWidth = width;
1008    mHeight = height;
1009}
1010
1011void DisplayListRenderer::prepareDirty(float left, float top,
1012        float right, float bottom, bool opaque) {
1013    mSnapshot = new Snapshot(mFirstSnapshot,
1014            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
1015    mSaveCount = 1;
1016    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
1017    mRestoreSaveCount = -1;
1018}
1019
1020void DisplayListRenderer::finish() {
1021    insertRestoreToCount();
1022    OpenGLRenderer::finish();
1023}
1024
1025void DisplayListRenderer::interrupt() {
1026}
1027
1028void DisplayListRenderer::resume() {
1029}
1030
1031bool DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
1032    // Ignore dirty during recording, it matters only when we replay
1033    addOp(DisplayList::DrawGLFunction);
1034    addInt((int) functor);
1035    return false; // No invalidate needed at record-time
1036}
1037
1038int DisplayListRenderer::save(int flags) {
1039    addOp(DisplayList::Save);
1040    addInt(flags);
1041    return OpenGLRenderer::save(flags);
1042}
1043
1044void DisplayListRenderer::restore() {
1045    if (mRestoreSaveCount < 0) {
1046        addOp(DisplayList::Restore);
1047    } else {
1048        mRestoreSaveCount--;
1049    }
1050    OpenGLRenderer::restore();
1051}
1052
1053void DisplayListRenderer::restoreToCount(int saveCount) {
1054    mRestoreSaveCount = saveCount;
1055    OpenGLRenderer::restoreToCount(saveCount);
1056}
1057
1058int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1059        SkPaint* p, int flags) {
1060    addOp(DisplayList::SaveLayer);
1061    addBounds(left, top, right, bottom);
1062    addPaint(p);
1063    addInt(flags);
1064    return OpenGLRenderer::save(flags);
1065}
1066
1067int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1068        int alpha, int flags) {
1069    addOp(DisplayList::SaveLayerAlpha);
1070    addBounds(left, top, right, bottom);
1071    addInt(alpha);
1072    addInt(flags);
1073    return OpenGLRenderer::save(flags);
1074}
1075
1076void DisplayListRenderer::translate(float dx, float dy) {
1077    addOp(DisplayList::Translate);
1078    addPoint(dx, dy);
1079    OpenGLRenderer::translate(dx, dy);
1080}
1081
1082void DisplayListRenderer::rotate(float degrees) {
1083    addOp(DisplayList::Rotate);
1084    addFloat(degrees);
1085    OpenGLRenderer::rotate(degrees);
1086}
1087
1088void DisplayListRenderer::scale(float sx, float sy) {
1089    addOp(DisplayList::Scale);
1090    addPoint(sx, sy);
1091    OpenGLRenderer::scale(sx, sy);
1092}
1093
1094void DisplayListRenderer::skew(float sx, float sy) {
1095    addOp(DisplayList::Skew);
1096    addPoint(sx, sy);
1097    OpenGLRenderer::skew(sx, sy);
1098}
1099
1100void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1101    addOp(DisplayList::SetMatrix);
1102    addMatrix(matrix);
1103    OpenGLRenderer::setMatrix(matrix);
1104}
1105
1106void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1107    addOp(DisplayList::ConcatMatrix);
1108    addMatrix(matrix);
1109    OpenGLRenderer::concatMatrix(matrix);
1110}
1111
1112bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1113        SkRegion::Op op) {
1114    addOp(DisplayList::ClipRect);
1115    addBounds(left, top, right, bottom);
1116    addInt(op);
1117    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1118}
1119
1120bool DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1121        uint32_t width, uint32_t height, Rect& dirty, uint32_t level) {
1122    // dirty is an out parameter and should not be recorded,
1123    // it matters only when replaying the display list
1124    addOp(DisplayList::DrawDisplayList);
1125    addDisplayList(displayList);
1126    addSize(width, height);
1127    return false;
1128}
1129
1130void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1131    addOp(DisplayList::DrawLayer);
1132    addInt((int) layer);
1133    addPoint(x, y);
1134    addPaint(paint);
1135}
1136
1137void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
1138        SkPaint* paint) {
1139    addOp(DisplayList::DrawBitmap);
1140    addBitmap(bitmap);
1141    addPoint(left, top);
1142    addPaint(paint);
1143}
1144
1145void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
1146        SkPaint* paint) {
1147    addOp(DisplayList::DrawBitmapMatrix);
1148    addBitmap(bitmap);
1149    addMatrix(matrix);
1150    addPaint(paint);
1151}
1152
1153void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1154        float srcRight, float srcBottom, float dstLeft, float dstTop,
1155        float dstRight, float dstBottom, SkPaint* paint) {
1156    addOp(DisplayList::DrawBitmapRect);
1157    addBitmap(bitmap);
1158    addBounds(srcLeft, srcTop, srcRight, srcBottom);
1159    addBounds(dstLeft, dstTop, dstRight, dstBottom);
1160    addPaint(paint);
1161}
1162
1163void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1164        float* vertices, int* colors, SkPaint* paint) {
1165    addOp(DisplayList::DrawBitmapMesh);
1166    addBitmap(bitmap);
1167    addInt(meshWidth);
1168    addInt(meshHeight);
1169    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1170    if (colors) {
1171        addInt(1);
1172        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1173    } else {
1174        addInt(0);
1175    }
1176    addPaint(paint);
1177}
1178
1179void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
1180        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
1181        float left, float top, float right, float bottom, SkPaint* paint) {
1182    addOp(DisplayList::DrawPatch);
1183    addBitmap(bitmap);
1184    addInts(xDivs, width);
1185    addInts(yDivs, height);
1186    addUInts(colors, numColors);
1187    addBounds(left, top, right, bottom);
1188    addPaint(paint);
1189}
1190
1191void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1192    addOp(DisplayList::DrawColor);
1193    addInt(color);
1194    addInt(mode);
1195}
1196
1197void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1198        SkPaint* paint) {
1199    addOp(DisplayList::DrawRect);
1200    addBounds(left, top, right, bottom);
1201    addPaint(paint);
1202}
1203
1204void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1205            float rx, float ry, SkPaint* paint) {
1206    addOp(DisplayList::DrawRoundRect);
1207    addBounds(left, top, right, bottom);
1208    addPoint(rx, ry);
1209    addPaint(paint);
1210}
1211
1212void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1213    addOp(DisplayList::DrawCircle);
1214    addPoint(x, y);
1215    addFloat(radius);
1216    addPaint(paint);
1217}
1218
1219void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1220        SkPaint* paint) {
1221    addOp(DisplayList::DrawOval);
1222    addBounds(left, top, right, bottom);
1223    addPaint(paint);
1224}
1225
1226void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1227        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1228    addOp(DisplayList::DrawArc);
1229    addBounds(left, top, right, bottom);
1230    addPoint(startAngle, sweepAngle);
1231    addInt(useCenter ? 1 : 0);
1232    addPaint(paint);
1233}
1234
1235void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1236    addOp(DisplayList::DrawPath);
1237    addPath(path);
1238    addPaint(paint);
1239}
1240
1241void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1242    addOp(DisplayList::DrawLines);
1243    addFloats(points, count);
1244    addPaint(paint);
1245}
1246
1247void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1248    addOp(DisplayList::DrawPoints);
1249    addFloats(points, count);
1250    addPaint(paint);
1251}
1252
1253void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
1254        float x, float y, SkPaint* paint, float length) {
1255    if (count <= 0) return;
1256    addOp(DisplayList::DrawText);
1257    addText(text, bytesCount);
1258    addInt(count);
1259    addPoint(x, y);
1260    // TODO: We should probably make a copy of the paint instead of modifying
1261    //       it; modifying the paint will change its generationID the first
1262    //       time, which might impact caches. More investigation needed to
1263    //       see if it matters.
1264    //       If we make a copy, then drawTextDecorations() should *not* make
1265    //       its own copy as it does right now.
1266    // Beware: this needs Glyph encoding (already done on the Paint constructor)
1267    paint->setAntiAlias(true);
1268    addPaint(paint);
1269    addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length);
1270}
1271
1272void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
1273        const float* positions, SkPaint* paint) {
1274    if (count <= 0) return;
1275    addOp(DisplayList::DrawPosText);
1276    addText(text, bytesCount);
1277    addInt(count);
1278    addFloats(positions, count * 2);
1279    paint->setAntiAlias(true);
1280    addPaint(paint);
1281}
1282
1283void DisplayListRenderer::resetShader() {
1284    addOp(DisplayList::ResetShader);
1285}
1286
1287void DisplayListRenderer::setupShader(SkiaShader* shader) {
1288    addOp(DisplayList::SetupShader);
1289    addShader(shader);
1290}
1291
1292void DisplayListRenderer::resetColorFilter() {
1293    addOp(DisplayList::ResetColorFilter);
1294}
1295
1296void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1297    addOp(DisplayList::SetupColorFilter);
1298    addColorFilter(filter);
1299}
1300
1301void DisplayListRenderer::resetShadow() {
1302    addOp(DisplayList::ResetShadow);
1303}
1304
1305void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1306    addOp(DisplayList::SetupShadow);
1307    addFloat(radius);
1308    addPoint(dx, dy);
1309    addInt(color);
1310}
1311
1312void DisplayListRenderer::resetPaintFilter() {
1313    addOp(DisplayList::ResetPaintFilter);
1314}
1315
1316void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
1317    addOp(DisplayList::SetupPaintFilter);
1318    addInt(clearBits);
1319    addInt(setBits);
1320}
1321
1322}; // namespace uirenderer
1323}; // namespace android
1324