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