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