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