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