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