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