DisplayListRenderer.cpp revision 45e4c3df6c00ac98ff6144de9af574877d4fff19
1289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza/*
2289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Copyright (C) 2010 The Android Open Source Project
3289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *
4289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Licensed under the Apache License, Version 2.0 (the "License");
5289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * you may not use this file except in compliance with the License.
6289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * You may obtain a copy of the License at
7289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *
8289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *      http://www.apache.org/licenses/LICENSE-2.0
9289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *
10289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Unless required by applicable law or agreed to in writing, software
11289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * distributed under the License is distributed on an "AS IS" BASIS,
12289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * See the License for the specific language governing permissions and
14289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * limitations under the License.
15289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza */
16289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
173e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza#define LOG_TAG "OpenGLRenderer"
183e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza
193e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza#include <SkCamera.h>
203e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza
21289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <private/hwui/DrawGlInfo.h>
22289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
23cece164b23dbb368de1be2112827dd2df0ab2b5cMark Salyzyn#include "DisplayListLogBuffer.h"
24cece164b23dbb368de1be2112827dd2df0ab2b5cMark Salyzyn#include "DisplayListRenderer.h"
25289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include "Caches.h"
26289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
27289ade165e60b5f71734d30e535f16eb1f4313adDan Stozanamespace android {
283e96f1982fda358424b0b75f394cbf7c1794a072Dan Stozanamespace uirenderer {
29f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza
303e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza///////////////////////////////////////////////////////////////////////////////
313e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza// Display list
32289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza///////////////////////////////////////////////////////////////////////////////
33289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
34289ade165e60b5f71734d30e535f16eb1f4313adDan Stozaconst char* DisplayList::OP_NAMES[] = {
35289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "Save",
36289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "Restore",
37289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "RestoreToCount",
38289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "SaveLayer",
39289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "SaveLayerAlpha",
40289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "Translate",
41289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "Rotate",
42289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "Scale",
43289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "Skew",
44289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "SetMatrix",
45289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "ConcatMatrix",
46289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "ClipRect",
47289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawDisplayList",
48289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawLayer",
49289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawBitmap",
50289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawBitmapMatrix",
51289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawBitmapRect",
52289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawBitmapData",
53f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza    "DrawBitmapMesh",
54289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawPatch",
55289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawColor",
56289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawRect",
57289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawRoundRect",
58289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawCircle",
59289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawOval",
60289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawArc",
61289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawPath",
62289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawLines",
63289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawPoints",
64289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawTextOnPath",
65289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawPosText",
66289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    "DrawText",
6778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour    "ResetShader",
6878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour    "SetupShader",
6978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour    "ResetColorFilter",
703e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    "SetupColorFilter",
713e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    "ResetShadow",
723e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    "SetupShadow",
733e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    "ResetPaintFilter",
743e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    "SetupPaintFilter",
753e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    "DrawGLFunction"
763e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza};
773e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza
783e96f1982fda358424b0b75f394cbf7c1794a072Dan Stozavoid DisplayList::outputLogBuffer(int fd) {
79289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
80289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    if (logBuffer.isEmpty()) {
81289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        return;
82289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
83289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
84289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    FILE *file = fdopen(fd, "a");
85289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
86289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    fprintf(file, "\nRecent DisplayList operations\n");
87289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    logBuffer.outputCommands(file, OP_NAMES);
88289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
89cece164b23dbb368de1be2112827dd2df0ab2b5cMark Salyzyn    String8 cachesLog;
90289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    Caches::getInstance().dumpMemoryUsage(cachesLog);
91289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    fprintf(file, "\nCaches:\n%s", cachesLog.string());
92289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    fprintf(file, "\n");
93289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
94289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    fflush(file);
95289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza}
96289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
97289ade165e60b5f71734d30e535f16eb1f4313adDan StozaDisplayList::DisplayList(const DisplayListRenderer& recorder) :
98289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
99cece164b23dbb368de1be2112827dd2df0ab2b5cMark Salyzyn    mStaticMatrix(NULL), mAnimationMatrix(NULL) {
100289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
101289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    initFromDisplayListRenderer(recorder);
102289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza}
103289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
104289ade165e60b5f71734d30e535f16eb1f4313adDan StozaDisplayList::~DisplayList() {
105289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    clearResources();
1063e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza}
107289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
108289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid DisplayList::initProperties() {
109289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mLeft = 0;
110289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mTop = 0;
111289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mRight = 0;
112289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mBottom = 0;
113289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mClipChildren = true;
114289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mAlpha = 1;
115289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mMultipliedAlpha = 255;
116289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mHasOverlappingRendering = true;
117289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mTranslationX = 0;
118289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mTranslationY = 0;
119289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mRotation = 0;
120289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mRotationX = 0;
121289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mRotationY= 0;
122289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mScaleX = 1;
123289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mScaleY = 1;
124289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mPivotX = 0;
125289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mPivotY = 0;
126289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mCameraDistance = 0;
127289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mMatrixDirty = false;
128289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mMatrixFlags = 0;
129289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mPrevWidth = -1;
130289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mPrevHeight = -1;
131289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mWidth = 0;
132289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mHeight = 0;
133289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mPivotExplicitlySet = false;
134289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mCaching = false;
135289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza}
136289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
137289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
138289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    if (displayList) {
139289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        DISPLAY_LIST_LOGD("Deferring display list destruction");
140289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        Caches::getInstance().deleteDisplayListDeferred(displayList);
141289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
142289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza}
143289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
144289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid DisplayList::clearResources() {
145289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    sk_free((void*) mReader.base());
146289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
147289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    delete mTransformMatrix;
148289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    delete mTransformCamera;
149289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    delete mTransformMatrix3D;
150289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    delete mStaticMatrix;
151289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    delete mAnimationMatrix;
152289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
153289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mTransformMatrix = NULL;
154289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mTransformCamera = NULL;
155289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mTransformMatrix3D = NULL;
156289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mStaticMatrix = NULL;
157289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mAnimationMatrix = NULL;
158289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
159289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    Caches& caches = Caches::getInstance();
160289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    caches.resourceCache.lock();
161289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
162289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    for (size_t i = 0; i < mBitmapResources.size(); i++) {
163289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
1643e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    }
165289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
166289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
167289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
168289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        caches.resourceCache.decrementRefcountLocked(bitmap);
169289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        caches.resourceCache.destructorLocked(bitmap);
170289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
171289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
172289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    for (size_t i = 0; i < mFilterResources.size(); i++) {
173289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
174289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
175289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
1763e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza    for (size_t i = 0; i < mShaders.size(); i++) {
177289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
1788f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn        caches.resourceCache.destructorLocked(mShaders.itemAt(i));
1798f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn    }
180289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
181289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    for (size_t i = 0; i < mSourcePaths.size(); i++) {
182289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
183289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
184289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
185289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    caches.resourceCache.unlock();
186289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
187289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    for (size_t i = 0; i < mPaints.size(); i++) {
188289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        delete mPaints.itemAt(i);
189289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
190289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
191289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    for (size_t i = 0; i < mPaths.size(); i++) {
192289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        SkPath* path = mPaths.itemAt(i);
193289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        caches.pathCache.remove(path);
194289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        delete path;
195289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
196289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
19799b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza    for (size_t i = 0; i < mMatrices.size(); i++) {
198289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        delete mMatrices.itemAt(i);
199289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
200289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
201289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mBitmapResources.clear();
202289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mOwnedBitmapResources.clear();
203289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mFilterResources.clear();
204289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mShaders.clear();
205289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mSourcePaths.clear();
206289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mPaints.clear();
207289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mPaths.clear();
208289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mMatrices.clear();
209289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza}
2103e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza
211289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
212289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    const SkWriter32& writer = recorder.writeStream();
213289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    init();
214289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
215289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    if (writer.size() == 0) {
216289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        return;
217289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
2188f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn
2198f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn    if (reusing) {
220289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        // re-using display list - clear out previous allocations
221289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza        clearResources();
222289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
223289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    initProperties();
224289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
225289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mSize = writer.size();
226289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    void* buffer = sk_malloc_throw(mSize);
227289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    writer.flatten(buffer);
228289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    mReader.setMemory(buffer, mSize);
229289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza
230289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    Caches& caches = Caches::getInstance();
23178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour    caches.resourceCache.lock();
23278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour
23378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour    const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
23478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour    for (size_t i = 0; i < bitmapResources.size(); i++) {
23578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour        SkBitmap* resource = bitmapResources.itemAt(i);
23678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour        mBitmapResources.add(resource);
23778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour        caches.resourceCache.incrementRefcountLocked(resource);
238289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza    }
239
240    const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
241    for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
242        SkBitmap* resource = ownedBitmapResources.itemAt(i);
243        mOwnedBitmapResources.add(resource);
244        caches.resourceCache.incrementRefcountLocked(resource);
245    }
246
247    const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
248    for (size_t i = 0; i < filterResources.size(); i++) {
249        SkiaColorFilter* resource = filterResources.itemAt(i);
250        mFilterResources.add(resource);
251        caches.resourceCache.incrementRefcountLocked(resource);
252    }
253
254    const Vector<SkiaShader*>& shaders = recorder.getShaders();
255    for (size_t i = 0; i < shaders.size(); i++) {
256        SkiaShader* resource = shaders.itemAt(i);
257        mShaders.add(resource);
258        caches.resourceCache.incrementRefcountLocked(resource);
259    }
260
261    const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
262    for (size_t i = 0; i < sourcePaths.size(); i++) {
263        mSourcePaths.add(sourcePaths.itemAt(i));
264        caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
265    }
266
267    caches.resourceCache.unlock();
268
269    const Vector<SkPaint*>& paints = recorder.getPaints();
270    for (size_t i = 0; i < paints.size(); i++) {
271        mPaints.add(paints.itemAt(i));
272    }
273
274    const Vector<SkPath*>& paths = recorder.getPaths();
275    for (size_t i = 0; i < paths.size(); i++) {
276        mPaths.add(paths.itemAt(i));
277    }
278
279    const Vector<SkMatrix*>& matrices = recorder.getMatrices();
280    for (size_t i = 0; i < matrices.size(); i++) {
281        mMatrices.add(matrices.itemAt(i));
282    }
283}
284
285void DisplayList::init() {
286    mSize = 0;
287    mIsRenderable = true;
288}
289
290size_t DisplayList::getSize() {
291    return mSize;
292}
293
294/**
295 * This function is a simplified version of replay(), where we simply retrieve and log the
296 * display list. This function should remain in sync with the replay() function.
297 */
298void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
299    TextContainer text;
300
301    uint32_t count = (level + 1) * 2;
302    char indent[count + 1];
303    for (uint32_t i = 0; i < count; i++) {
304        indent[i] = ' ';
305    }
306    indent[count] = '\0';
307    ALOGD("%sStart display list (%p, %s, render=%d)", (char*) indent + 2, this,
308            mName.string(), isRenderable());
309
310    ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
311    int saveCount = renderer.getSaveCount() - 1;
312
313    outputViewProperties(renderer, (char*) indent);
314    mReader.rewind();
315
316    while (!mReader.eof()) {
317        int op = mReader.readInt();
318        if (op & OP_MAY_BE_SKIPPED_MASK) {
319            int skip = mReader.readInt();
320            ALOGD("%sSkip %d", (char*) indent, skip);
321            op &= ~OP_MAY_BE_SKIPPED_MASK;
322        }
323
324        switch (op) {
325            case DrawGLFunction: {
326                Functor *functor = (Functor *) getInt();
327                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
328            }
329            break;
330            case Save: {
331                int rendererNum = getInt();
332                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
333            }
334            break;
335            case Restore: {
336                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
337            }
338            break;
339            case RestoreToCount: {
340                int restoreCount = saveCount + getInt();
341                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
342            }
343            break;
344            case SaveLayer: {
345                float f1 = getFloat();
346                float f2 = getFloat();
347                float f3 = getFloat();
348                float f4 = getFloat();
349                SkPaint* paint = getPaint(renderer);
350                int flags = getInt();
351                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
352                        OP_NAMES[op], f1, f2, f3, f4, paint, flags);
353            }
354            break;
355            case SaveLayerAlpha: {
356                float f1 = getFloat();
357                float f2 = getFloat();
358                float f3 = getFloat();
359                float f4 = getFloat();
360                int alpha = getInt();
361                int flags = getInt();
362                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
363                        OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
364            }
365            break;
366            case Translate: {
367                float f1 = getFloat();
368                float f2 = getFloat();
369                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
370            }
371            break;
372            case Rotate: {
373                float rotation = getFloat();
374                ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
375            }
376            break;
377            case Scale: {
378                float sx = getFloat();
379                float sy = getFloat();
380                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
381            }
382            break;
383            case Skew: {
384                float sx = getFloat();
385                float sy = getFloat();
386                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
387            }
388            break;
389            case SetMatrix: {
390                SkMatrix* matrix = getMatrix();
391                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
392            }
393            break;
394            case ConcatMatrix: {
395                SkMatrix* matrix = getMatrix();
396                ALOGD("%s%s new concat %p: [%f, %f, %f]   [%f, %f, %f]   [%f, %f, %f]",
397                        (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1),
398                        matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5),
399                        matrix->get(6), matrix->get(7), matrix->get(8));
400            }
401            break;
402            case ClipRect: {
403                float f1 = getFloat();
404                float f2 = getFloat();
405                float f3 = getFloat();
406                float f4 = getFloat();
407                int regionOp = getInt();
408                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
409                        f1, f2, f3, f4, regionOp);
410            }
411            break;
412            case DrawDisplayList: {
413                DisplayList* displayList = getDisplayList();
414                int32_t flags = getInt();
415                ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
416                        displayList, mWidth, mHeight, flags, level + 1);
417                renderer.outputDisplayList(displayList, level + 1);
418            }
419            break;
420            case DrawLayer: {
421                Layer* layer = (Layer*) getInt();
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                        layer, x, y, paint);
427            }
428            break;
429            case DrawBitmap: {
430                SkBitmap* bitmap = getBitmap();
431                float x = getFloat();
432                float y = getFloat();
433                SkPaint* paint = getPaint(renderer);
434                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
435                        bitmap, x, y, paint);
436            }
437            break;
438            case DrawBitmapMatrix: {
439                SkBitmap* bitmap = getBitmap();
440                SkMatrix* matrix = getMatrix();
441                SkPaint* paint = getPaint(renderer);
442                ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
443                        bitmap, matrix, paint);
444            }
445            break;
446            case DrawBitmapRect: {
447                SkBitmap* bitmap = getBitmap();
448                float f1 = getFloat();
449                float f2 = getFloat();
450                float f3 = getFloat();
451                float f4 = getFloat();
452                float f5 = getFloat();
453                float f6 = getFloat();
454                float f7 = getFloat();
455                float f8 = getFloat();
456                SkPaint* paint = getPaint(renderer);
457                ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
458                        (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
459            }
460            break;
461            case DrawBitmapData: {
462                SkBitmap* bitmap = getBitmapData();
463                float x = getFloat();
464                float y = getFloat();
465                SkPaint* paint = getPaint(renderer);
466                ALOGD("%s%s %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], x, y, paint);
467            }
468            break;
469            case DrawBitmapMesh: {
470                int verticesCount = 0;
471                uint32_t colorsCount = 0;
472                SkBitmap* bitmap = getBitmap();
473                uint32_t meshWidth = getInt();
474                uint32_t meshHeight = getInt();
475                float* vertices = getFloats(verticesCount);
476                bool hasColors = getInt();
477                int* colors = hasColors ? getInts(colorsCount) : NULL;
478                SkPaint* paint = getPaint(renderer);
479                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
480            }
481            break;
482            case DrawPatch: {
483                int32_t* xDivs = NULL;
484                int32_t* yDivs = NULL;
485                uint32_t* colors = NULL;
486                uint32_t xDivsCount = 0;
487                uint32_t yDivsCount = 0;
488                int8_t numColors = 0;
489                SkBitmap* bitmap = getBitmap();
490                xDivs = getInts(xDivsCount);
491                yDivs = getInts(yDivsCount);
492                colors = getUInts(numColors);
493                float left = getFloat();
494                float top = getFloat();
495                float right = getFloat();
496                float bottom = getFloat();
497                int alpha = getInt();
498                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
499                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
500                        left, top, right, bottom);
501            }
502            break;
503            case DrawColor: {
504                int color = getInt();
505                int xferMode = getInt();
506                ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
507            }
508            break;
509            case DrawRect: {
510                float f1 = getFloat();
511                float f2 = getFloat();
512                float f3 = getFloat();
513                float f4 = getFloat();
514                SkPaint* paint = getPaint(renderer);
515                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
516                        f1, f2, f3, f4, paint);
517            }
518            break;
519            case DrawRoundRect: {
520                float f1 = getFloat();
521                float f2 = getFloat();
522                float f3 = getFloat();
523                float f4 = getFloat();
524                float f5 = getFloat();
525                float f6 = getFloat();
526                SkPaint* paint = getPaint(renderer);
527                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
528                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
529            }
530            break;
531            case DrawCircle: {
532                float f1 = getFloat();
533                float f2 = getFloat();
534                float f3 = getFloat();
535                SkPaint* paint = getPaint(renderer);
536                ALOGD("%s%s %.2f, %.2f, %.2f, %p",
537                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
538            }
539            break;
540            case DrawOval: {
541                float f1 = getFloat();
542                float f2 = getFloat();
543                float f3 = getFloat();
544                float f4 = getFloat();
545                SkPaint* paint = getPaint(renderer);
546                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
547                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
548            }
549            break;
550            case DrawArc: {
551                float f1 = getFloat();
552                float f2 = getFloat();
553                float f3 = getFloat();
554                float f4 = getFloat();
555                float f5 = getFloat();
556                float f6 = getFloat();
557                int i1 = getInt();
558                SkPaint* paint = getPaint(renderer);
559                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
560                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
561            }
562            break;
563            case DrawPath: {
564                SkPath* path = getPath();
565                SkPaint* paint = getPaint(renderer);
566                ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
567            }
568            break;
569            case DrawLines: {
570                int count = 0;
571                float* points = getFloats(count);
572                SkPaint* paint = getPaint(renderer);
573                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
574            }
575            break;
576            case DrawPoints: {
577                int count = 0;
578                float* points = getFloats(count);
579                SkPaint* paint = getPaint(renderer);
580                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
581            }
582            break;
583            case DrawTextOnPath: {
584                getText(&text);
585                int32_t count = getInt();
586                SkPath* path = getPath();
587                float hOffset = getFloat();
588                float vOffset = getFloat();
589                SkPaint* paint = getPaint(renderer);
590                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
591                    text.text(), text.length(), count, paint);
592            }
593            break;
594            case DrawPosText: {
595                getText(&text);
596                int count = getInt();
597                int positionsCount = 0;
598                float* positions = getFloats(positionsCount);
599                SkPaint* paint = getPaint(renderer);
600                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
601                        text.text(), text.length(), count, paint);
602            }
603            break;
604            case DrawText: {
605                getText(&text);
606                int32_t count = getInt();
607                float x = getFloat();
608                float y = getFloat();
609                int32_t positionsCount = 0;
610                float* positions = getFloats(positionsCount);
611                SkPaint* paint = getPaint(renderer);
612                float length = getFloat();
613                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
614                        text.text(), text.length(), count, paint);
615            }
616            break;
617            case ResetShader: {
618                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
619            }
620            break;
621            case SetupShader: {
622                SkiaShader* shader = getShader();
623                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
624            }
625            break;
626            case ResetColorFilter: {
627                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
628            }
629            break;
630            case SetupColorFilter: {
631                SkiaColorFilter *colorFilter = getColorFilter();
632                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
633            }
634            break;
635            case ResetShadow: {
636                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
637            }
638            break;
639            case SetupShadow: {
640                float radius = getFloat();
641                float dx = getFloat();
642                float dy = getFloat();
643                int color = getInt();
644                ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
645                        radius, dx, dy, color);
646            }
647            break;
648            case ResetPaintFilter: {
649                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
650            }
651            break;
652            case SetupPaintFilter: {
653                int clearBits = getInt();
654                int setBits = getInt();
655                ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits);
656            }
657            break;
658            default:
659                ALOGD("Display List error: op not handled: %s%s",
660                        (char*) indent, OP_NAMES[op]);
661                break;
662        }
663    }
664    ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string());
665}
666
667void DisplayList::updateMatrix() {
668    if (mMatrixDirty) {
669        if (!mTransformMatrix) {
670            mTransformMatrix = new SkMatrix();
671        }
672        if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
673            mTransformMatrix->reset();
674        } else {
675            if (!mPivotExplicitlySet) {
676                if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
677                    mPrevWidth = mWidth;
678                    mPrevHeight = mHeight;
679                    mPivotX = mPrevWidth / 2;
680                    mPivotY = mPrevHeight / 2;
681                }
682            }
683            if ((mMatrixFlags & ROTATION_3D) == 0) {
684                mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
685                mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
686                mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
687            } else {
688                if (!mTransformCamera) {
689                    mTransformCamera = new Sk3DView();
690                    mTransformMatrix3D = new SkMatrix();
691                }
692                mTransformMatrix->reset();
693                mTransformCamera->save();
694                mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
695                mTransformCamera->rotateX(mRotationX);
696                mTransformCamera->rotateY(mRotationY);
697                mTransformCamera->rotateZ(-mRotation);
698                mTransformCamera->getMatrix(mTransformMatrix3D);
699                mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
700                mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
701                        mPivotY + mTranslationY);
702                mTransformMatrix->postConcat(*mTransformMatrix3D);
703                mTransformCamera->restore();
704            }
705        }
706        mMatrixDirty = false;
707    }
708}
709
710void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
711    updateMatrix();
712    if (mLeft != 0 || mTop != 0) {
713        ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
714    }
715    if (mStaticMatrix) {
716        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
717                indent, "ConcatMatrix (static)", mStaticMatrix,
718                mStaticMatrix->get(0), mStaticMatrix->get(1),
719                mStaticMatrix->get(2), mStaticMatrix->get(3),
720                mStaticMatrix->get(4), mStaticMatrix->get(5),
721                mStaticMatrix->get(6), mStaticMatrix->get(7),
722                mStaticMatrix->get(8));
723    }
724    if (mAnimationMatrix) {
725        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
726                indent, "ConcatMatrix (animation)", mAnimationMatrix,
727                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
728                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
729                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
730                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
731                mAnimationMatrix->get(8));
732    }
733    if (mMatrixFlags != 0) {
734        if (mMatrixFlags == TRANSLATION) {
735            ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
736        } else {
737            ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
738                    indent, "ConcatMatrix", mTransformMatrix,
739                    mTransformMatrix->get(0), mTransformMatrix->get(1),
740                    mTransformMatrix->get(2), mTransformMatrix->get(3),
741                    mTransformMatrix->get(4), mTransformMatrix->get(5),
742                    mTransformMatrix->get(6), mTransformMatrix->get(7),
743                    mTransformMatrix->get(8));
744        }
745    }
746    if (mAlpha < 1 && !mCaching) {
747        // TODO: should be able to store the size of a DL at record time and not
748        // have to pass it into this call. In fact, this information might be in the
749        // location/size info that we store with the new native transform data.
750        int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
751        if (mClipChildren) {
752            flags |= SkCanvas::kClipToLayer_SaveFlag;
753        }
754        ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
755                (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
756                mMultipliedAlpha, flags);
757    }
758    if (mClipChildren) {
759        ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
760                (float) mRight - mLeft, (float) mBottom - mTop);
761    }
762}
763
764void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
765#if DEBUG_DISPLAY_LIST
766        uint32_t count = (level + 1) * 2;
767        char indent[count + 1];
768        for (uint32_t i = 0; i < count; i++) {
769            indent[i] = ' ';
770        }
771        indent[count] = '\0';
772#endif
773    updateMatrix();
774    if (mLeft != 0 || mTop != 0) {
775        DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
776        renderer.translate(mLeft, mTop);
777    }
778    if (mStaticMatrix) {
779        DISPLAY_LIST_LOGD(
780                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
781                indent, "ConcatMatrix (static)", mStaticMatrix,
782                mStaticMatrix->get(0), mStaticMatrix->get(1),
783                mStaticMatrix->get(2), mStaticMatrix->get(3),
784                mStaticMatrix->get(4), mStaticMatrix->get(5),
785                mStaticMatrix->get(6), mStaticMatrix->get(7),
786                mStaticMatrix->get(8));
787        renderer.concatMatrix(mStaticMatrix);
788    } else if (mAnimationMatrix) {
789        DISPLAY_LIST_LOGD(
790                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
791                indent, "ConcatMatrix (animation)", mAnimationMatrix,
792                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
793                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
794                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
795                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
796                mAnimationMatrix->get(8));
797        renderer.concatMatrix(mAnimationMatrix);
798    }
799    if (mMatrixFlags != 0) {
800        if (mMatrixFlags == TRANSLATION) {
801            DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
802            renderer.translate(mTranslationX, mTranslationY);
803        } else {
804            DISPLAY_LIST_LOGD(
805                    "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
806                    indent, "ConcatMatrix", mTransformMatrix,
807                    mTransformMatrix->get(0), mTransformMatrix->get(1),
808                    mTransformMatrix->get(2), mTransformMatrix->get(3),
809                    mTransformMatrix->get(4), mTransformMatrix->get(5),
810                    mTransformMatrix->get(6), mTransformMatrix->get(7),
811                    mTransformMatrix->get(8));
812            renderer.concatMatrix(mTransformMatrix);
813        }
814    }
815    if (mAlpha < 1 && !mCaching) {
816        if (!mHasOverlappingRendering) {
817            DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
818            renderer.setAlpha(mAlpha);
819        } else {
820            // TODO: should be able to store the size of a DL at record time and not
821            // have to pass it into this call. In fact, this information might be in the
822            // location/size info that we store with the new native transform data.
823            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
824            if (mClipChildren) {
825                flags |= SkCanvas::kClipToLayer_SaveFlag;
826            }
827            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
828                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
829                    mMultipliedAlpha, flags);
830            renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
831                    mMultipliedAlpha, flags);
832        }
833    }
834    if (mClipChildren) {
835        DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
836                (float) mRight - mLeft, (float) mBottom - mTop);
837        renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
838                SkRegion::kIntersect_Op);
839    }
840}
841
842/**
843 * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
844 * in the output() function, since that function processes the same list of opcodes for the
845 * purposes of logging display list info for a given view.
846 */
847status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
848    status_t drawGlStatus = DrawGlInfo::kStatusDone;
849    TextContainer text;
850    mReader.rewind();
851
852#if DEBUG_DISPLAY_LIST
853    uint32_t count = (level + 1) * 2;
854    char indent[count + 1];
855    for (uint32_t i = 0; i < count; i++) {
856        indent[i] = ' ';
857    }
858    indent[count] = '\0';
859    Rect* clipRect = renderer.getClipRect();
860    DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
861            (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top,
862            clipRect->right, clipRect->bottom);
863#endif
864
865    renderer.startMark(mName.string());
866
867    int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
868    DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
869            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
870    setViewProperties(renderer, level);
871
872    if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
873        DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
874        renderer.restoreToCount(restoreTo);
875        renderer.endMark();
876        return drawGlStatus;
877    }
878
879    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
880    int saveCount = renderer.getSaveCount() - 1;
881
882    while (!mReader.eof()) {
883        int op = mReader.readInt();
884        if (op & OP_MAY_BE_SKIPPED_MASK) {
885            int32_t skip = mReader.readInt();
886            if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) {
887                mReader.skip(skip);
888                DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent,
889                        OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip);
890                continue;
891            } else {
892                op &= ~OP_MAY_BE_SKIPPED_MASK;
893            }
894        }
895        logBuffer.writeCommand(level, op);
896
897#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
898        Caches::getInstance().eventMark(strlen(OP_NAMES[op]), OP_NAMES[op]);
899#endif
900
901        switch (op) {
902            case DrawGLFunction: {
903                Functor *functor = (Functor *) getInt();
904                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
905                renderer.startMark("GL functor");
906                drawGlStatus |= renderer.callDrawGLFunction(functor, dirty);
907                renderer.endMark();
908            }
909            break;
910            case Save: {
911                int32_t rendererNum = getInt();
912                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
913                renderer.save(rendererNum);
914            }
915            break;
916            case Restore: {
917                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
918                renderer.restore();
919            }
920            break;
921            case RestoreToCount: {
922                int32_t restoreCount = saveCount + getInt();
923                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
924                renderer.restoreToCount(restoreCount);
925            }
926            break;
927            case SaveLayer: {
928                float f1 = getFloat();
929                float f2 = getFloat();
930                float f3 = getFloat();
931                float f4 = getFloat();
932                SkPaint* paint = getPaint(renderer);
933                int32_t flags = getInt();
934                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
935                        OP_NAMES[op], f1, f2, f3, f4, paint, flags);
936                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
937            }
938            break;
939            case SaveLayerAlpha: {
940                float f1 = getFloat();
941                float f2 = getFloat();
942                float f3 = getFloat();
943                float f4 = getFloat();
944                int32_t alpha = getInt();
945                int32_t flags = getInt();
946                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
947                        OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
948                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
949            }
950            break;
951            case Translate: {
952                float f1 = getFloat();
953                float f2 = getFloat();
954                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
955                renderer.translate(f1, f2);
956            }
957            break;
958            case Rotate: {
959                float rotation = getFloat();
960                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
961                renderer.rotate(rotation);
962            }
963            break;
964            case Scale: {
965                float sx = getFloat();
966                float sy = getFloat();
967                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
968                renderer.scale(sx, sy);
969            }
970            break;
971            case Skew: {
972                float sx = getFloat();
973                float sy = getFloat();
974                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
975                renderer.skew(sx, sy);
976            }
977            break;
978            case SetMatrix: {
979                SkMatrix* matrix = getMatrix();
980                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
981                renderer.setMatrix(matrix);
982            }
983            break;
984            case ConcatMatrix: {
985                SkMatrix* matrix = getMatrix();
986                DISPLAY_LIST_LOGD(
987                        "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
988                        (char*) indent, OP_NAMES[op], matrix,
989                        matrix->get(0), matrix->get(1), matrix->get(2),
990                        matrix->get(3), matrix->get(4), matrix->get(5),
991                        matrix->get(6), matrix->get(7), matrix->get(8));
992                renderer.concatMatrix(matrix);
993            }
994            break;
995            case ClipRect: {
996                float f1 = getFloat();
997                float f2 = getFloat();
998                float f3 = getFloat();
999                float f4 = getFloat();
1000                int32_t regionOp = getInt();
1001                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
1002                        f1, f2, f3, f4, regionOp);
1003                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
1004            }
1005            break;
1006            case DrawDisplayList: {
1007                DisplayList* displayList = getDisplayList();
1008                int32_t flags = getInt();
1009                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
1010                        displayList, mWidth, mHeight, flags, level + 1);
1011                drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1);
1012            }
1013            break;
1014            case DrawLayer: {
1015                int oldAlpha = -1;
1016                Layer* layer = (Layer*) getInt();
1017                float x = getFloat();
1018                float y = getFloat();
1019                SkPaint* paint = getPaint(renderer);
1020                if (mCaching && mMultipliedAlpha < 255) {
1021                    oldAlpha = layer->getAlpha();
1022                    layer->setAlpha(mMultipliedAlpha);
1023                }
1024                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1025                        layer, x, y, paint);
1026                drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
1027                if (oldAlpha >= 0) {
1028                    layer->setAlpha(oldAlpha);
1029                }
1030            }
1031            break;
1032            case DrawBitmap: {
1033                int oldAlpha = -1;
1034                SkBitmap* bitmap = getBitmap();
1035                float x = getFloat();
1036                float y = getFloat();
1037                SkPaint* paint = getPaint(renderer);
1038                if (mCaching && mMultipliedAlpha < 255) {
1039                    oldAlpha = paint->getAlpha();
1040                    paint->setAlpha(mMultipliedAlpha);
1041                }
1042                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1043                        bitmap, x, y, paint);
1044                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1045                if (oldAlpha >= 0) {
1046                    paint->setAlpha(oldAlpha);
1047                }
1048            }
1049            break;
1050            case DrawBitmapMatrix: {
1051                SkBitmap* bitmap = getBitmap();
1052                SkMatrix* matrix = getMatrix();
1053                SkPaint* paint = getPaint(renderer);
1054                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
1055                        bitmap, matrix, paint);
1056                drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
1057            }
1058            break;
1059            case DrawBitmapRect: {
1060                SkBitmap* bitmap = getBitmap();
1061                float f1 = getFloat();
1062                float f2 = getFloat();
1063                float f3 = getFloat();
1064                float f4 = getFloat();
1065                float f5 = getFloat();
1066                float f6 = getFloat();
1067                float f7 = getFloat();
1068                float f8 = getFloat();
1069                SkPaint* paint = getPaint(renderer);
1070                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1071                        (char*) indent, OP_NAMES[op], bitmap,
1072                        f1, f2, f3, f4, f5, f6, f7, f8,paint);
1073                drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
1074            }
1075            break;
1076            case DrawBitmapData: {
1077                SkBitmap* bitmap = getBitmapData();
1078                float x = getFloat();
1079                float y = getFloat();
1080                SkPaint* paint = getPaint(renderer);
1081                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1082                        bitmap, x, y, paint);
1083                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1084            }
1085            break;
1086            case DrawBitmapMesh: {
1087                int32_t verticesCount = 0;
1088                uint32_t colorsCount = 0;
1089
1090                SkBitmap* bitmap = getBitmap();
1091                uint32_t meshWidth = getInt();
1092                uint32_t meshHeight = getInt();
1093                float* vertices = getFloats(verticesCount);
1094                bool hasColors = getInt();
1095                int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
1096                SkPaint* paint = getPaint(renderer);
1097
1098                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1099                drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
1100                        colors, paint);
1101            }
1102            break;
1103            case DrawPatch: {
1104                int32_t* xDivs = NULL;
1105                int32_t* yDivs = NULL;
1106                uint32_t* colors = NULL;
1107                uint32_t xDivsCount = 0;
1108                uint32_t yDivsCount = 0;
1109                int8_t numColors = 0;
1110
1111                SkBitmap* bitmap = getBitmap();
1112
1113                xDivs = getInts(xDivsCount);
1114                yDivs = getInts(yDivsCount);
1115                colors = getUInts(numColors);
1116
1117                float left = getFloat();
1118                float top = getFloat();
1119                float right = getFloat();
1120                float bottom = getFloat();
1121
1122                int alpha = getInt();
1123                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
1124
1125                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1126                drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
1127                        xDivsCount, yDivsCount, numColors, left, top, right, bottom,
1128                        alpha, mode);
1129            }
1130            break;
1131            case DrawColor: {
1132                int32_t color = getInt();
1133                int32_t xferMode = getInt();
1134                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
1135                drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
1136            }
1137            break;
1138            case DrawRect: {
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", (char*) indent, OP_NAMES[op],
1145                        f1, f2, f3, f4, paint);
1146                drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
1147            }
1148            break;
1149            case DrawRoundRect: {
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                SkPaint* paint = getPaint(renderer);
1157                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1158                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
1159                drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
1160            }
1161            break;
1162            case DrawCircle: {
1163                float f1 = getFloat();
1164                float f2 = getFloat();
1165                float f3 = getFloat();
1166                SkPaint* paint = getPaint(renderer);
1167                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
1168                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
1169                drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
1170            }
1171            break;
1172            case DrawOval: {
1173                float f1 = getFloat();
1174                float f2 = getFloat();
1175                float f3 = getFloat();
1176                float f4 = getFloat();
1177                SkPaint* paint = getPaint(renderer);
1178                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
1179                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
1180                drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
1181            }
1182            break;
1183            case DrawArc: {
1184                float f1 = getFloat();
1185                float f2 = getFloat();
1186                float f3 = getFloat();
1187                float f4 = getFloat();
1188                float f5 = getFloat();
1189                float f6 = getFloat();
1190                int32_t i1 = getInt();
1191                SkPaint* paint = getPaint(renderer);
1192                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
1193                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
1194                drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
1195            }
1196            break;
1197            case DrawPath: {
1198                SkPath* path = getPath();
1199                SkPaint* paint = getPaint(renderer);
1200                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
1201                drawGlStatus |= renderer.drawPath(path, paint);
1202            }
1203            break;
1204            case DrawLines: {
1205                int32_t count = 0;
1206                float* points = getFloats(count);
1207                SkPaint* paint = getPaint(renderer);
1208                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1209                drawGlStatus |= renderer.drawLines(points, count, paint);
1210            }
1211            break;
1212            case DrawPoints: {
1213                int32_t count = 0;
1214                float* points = getFloats(count);
1215                SkPaint* paint = getPaint(renderer);
1216                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1217                drawGlStatus |= renderer.drawPoints(points, count, paint);
1218            }
1219            break;
1220            case DrawTextOnPath: {
1221                getText(&text);
1222                int32_t count = getInt();
1223                SkPath* path = getPath();
1224                float hOffset = getFloat();
1225                float vOffset = getFloat();
1226                SkPaint* paint = getPaint(renderer);
1227                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
1228                    text.text(), text.length(), count, paint);
1229                drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
1230                        hOffset, vOffset, paint);
1231            }
1232            break;
1233            case DrawPosText: {
1234                getText(&text);
1235                int32_t count = getInt();
1236                int32_t positionsCount = 0;
1237                float* positions = getFloats(positionsCount);
1238                SkPaint* paint = getPaint(renderer);
1239                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
1240                        OP_NAMES[op], text.text(), text.length(), count, paint);
1241                drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
1242                        positions, paint);
1243            }
1244            break;
1245            case DrawText: {
1246                getText(&text);
1247                int32_t count = getInt();
1248                float x = getFloat();
1249                float y = getFloat();
1250                int32_t positionsCount = 0;
1251                float* positions = getFloats(positionsCount);
1252                SkPaint* paint = getPaint(renderer);
1253                float length = getFloat();
1254                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
1255                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
1256                drawGlStatus |= renderer.drawText(text.text(), text.length(), count,
1257                        x, y, positions, paint, length);
1258            }
1259            break;
1260            case ResetShader: {
1261                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1262                renderer.resetShader();
1263            }
1264            break;
1265            case SetupShader: {
1266                SkiaShader* shader = getShader();
1267                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
1268                renderer.setupShader(shader);
1269            }
1270            break;
1271            case ResetColorFilter: {
1272                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1273                renderer.resetColorFilter();
1274            }
1275            break;
1276            case SetupColorFilter: {
1277                SkiaColorFilter *colorFilter = getColorFilter();
1278                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
1279                renderer.setupColorFilter(colorFilter);
1280            }
1281            break;
1282            case ResetShadow: {
1283                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1284                renderer.resetShadow();
1285            }
1286            break;
1287            case SetupShadow: {
1288                float radius = getFloat();
1289                float dx = getFloat();
1290                float dy = getFloat();
1291                int32_t color = getInt();
1292                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
1293                        radius, dx, dy, color);
1294                renderer.setupShadow(radius, dx, dy, color);
1295            }
1296            break;
1297            case ResetPaintFilter: {
1298                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1299                renderer.resetPaintFilter();
1300            }
1301            break;
1302            case SetupPaintFilter: {
1303                int32_t clearBits = getInt();
1304                int32_t setBits = getInt();
1305                DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
1306                        clearBits, setBits);
1307                renderer.setupPaintFilter(clearBits, setBits);
1308            }
1309            break;
1310            default:
1311                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
1312                        (char*) indent, OP_NAMES[op]);
1313                break;
1314        }
1315    }
1316
1317    DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
1318    renderer.restoreToCount(restoreTo);
1319    renderer.endMark();
1320
1321    DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
1322            drawGlStatus);
1323    return drawGlStatus;
1324}
1325
1326///////////////////////////////////////////////////////////////////////////////
1327// Base structure
1328///////////////////////////////////////////////////////////////////////////////
1329
1330DisplayListRenderer::DisplayListRenderer():
1331        mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE),
1332        mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
1333}
1334
1335DisplayListRenderer::~DisplayListRenderer() {
1336    reset();
1337}
1338
1339void DisplayListRenderer::reset() {
1340    mWriter.reset();
1341
1342    mCaches.resourceCache.lock();
1343
1344    for (size_t i = 0; i < mBitmapResources.size(); i++) {
1345        mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
1346    }
1347
1348    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
1349        mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
1350    }
1351
1352    for (size_t i = 0; i < mFilterResources.size(); i++) {
1353        mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
1354    }
1355
1356    for (size_t i = 0; i < mShaders.size(); i++) {
1357        mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
1358    }
1359
1360    for (size_t i = 0; i < mSourcePaths.size(); i++) {
1361        mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
1362    }
1363
1364    mCaches.resourceCache.unlock();
1365
1366    mBitmapResources.clear();
1367    mOwnedBitmapResources.clear();
1368    mFilterResources.clear();
1369    mSourcePaths.clear();
1370
1371    mShaders.clear();
1372    mShaderMap.clear();
1373
1374    mPaints.clear();
1375    mPaintMap.clear();
1376
1377    mPaths.clear();
1378    mPathMap.clear();
1379
1380    mMatrices.clear();
1381
1382    mHasDrawOps = false;
1383}
1384
1385///////////////////////////////////////////////////////////////////////////////
1386// Operations
1387///////////////////////////////////////////////////////////////////////////////
1388
1389DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
1390    if (!displayList) {
1391        displayList = new DisplayList(*this);
1392    } else {
1393        displayList->initFromDisplayListRenderer(*this, true);
1394    }
1395    displayList->setRenderable(mHasDrawOps);
1396    return displayList;
1397}
1398
1399bool DisplayListRenderer::isDeferred() {
1400    return true;
1401}
1402
1403void DisplayListRenderer::setViewport(int width, int height) {
1404    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
1405
1406    mWidth = width;
1407    mHeight = height;
1408}
1409
1410int DisplayListRenderer::prepareDirty(float left, float top,
1411        float right, float bottom, bool opaque) {
1412    mSnapshot = new Snapshot(mFirstSnapshot,
1413            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
1414    mSaveCount = 1;
1415
1416    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
1417    mDirtyClip = opaque;
1418
1419    mRestoreSaveCount = -1;
1420
1421    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1422}
1423
1424void DisplayListRenderer::finish() {
1425    insertRestoreToCount();
1426    insertTranlate();
1427}
1428
1429void DisplayListRenderer::interrupt() {
1430}
1431
1432void DisplayListRenderer::resume() {
1433}
1434
1435status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
1436    // Ignore dirty during recording, it matters only when we replay
1437    addOp(DisplayList::DrawGLFunction);
1438    addInt((int) functor);
1439    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1440}
1441
1442int DisplayListRenderer::save(int flags) {
1443    addOp(DisplayList::Save);
1444    addInt(flags);
1445    return OpenGLRenderer::save(flags);
1446}
1447
1448void DisplayListRenderer::restore() {
1449    if (mRestoreSaveCount < 0) {
1450        restoreToCount(getSaveCount() - 1);
1451        return;
1452    }
1453
1454    mRestoreSaveCount--;
1455    insertTranlate();
1456    OpenGLRenderer::restore();
1457}
1458
1459void DisplayListRenderer::restoreToCount(int saveCount) {
1460    mRestoreSaveCount = saveCount;
1461    insertTranlate();
1462    OpenGLRenderer::restoreToCount(saveCount);
1463}
1464
1465int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1466        SkPaint* p, int flags) {
1467    addOp(DisplayList::SaveLayer);
1468    addBounds(left, top, right, bottom);
1469    addPaint(p);
1470    addInt(flags);
1471    return OpenGLRenderer::save(flags);
1472}
1473
1474int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1475        int alpha, int flags) {
1476    addOp(DisplayList::SaveLayerAlpha);
1477    addBounds(left, top, right, bottom);
1478    addInt(alpha);
1479    addInt(flags);
1480    return OpenGLRenderer::save(flags);
1481}
1482
1483void DisplayListRenderer::translate(float dx, float dy) {
1484    mHasTranslate = true;
1485    mTranslateX += dx;
1486    mTranslateY += dy;
1487    insertRestoreToCount();
1488    OpenGLRenderer::translate(dx, dy);
1489}
1490
1491void DisplayListRenderer::rotate(float degrees) {
1492    addOp(DisplayList::Rotate);
1493    addFloat(degrees);
1494    OpenGLRenderer::rotate(degrees);
1495}
1496
1497void DisplayListRenderer::scale(float sx, float sy) {
1498    addOp(DisplayList::Scale);
1499    addPoint(sx, sy);
1500    OpenGLRenderer::scale(sx, sy);
1501}
1502
1503void DisplayListRenderer::skew(float sx, float sy) {
1504    addOp(DisplayList::Skew);
1505    addPoint(sx, sy);
1506    OpenGLRenderer::skew(sx, sy);
1507}
1508
1509void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1510    addOp(DisplayList::SetMatrix);
1511    addMatrix(matrix);
1512    OpenGLRenderer::setMatrix(matrix);
1513}
1514
1515void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1516    addOp(DisplayList::ConcatMatrix);
1517    addMatrix(matrix);
1518    OpenGLRenderer::concatMatrix(matrix);
1519}
1520
1521bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1522        SkRegion::Op op) {
1523    addOp(DisplayList::ClipRect);
1524    addBounds(left, top, right, bottom);
1525    addInt(op);
1526    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1527}
1528
1529status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1530        Rect& dirty, int32_t flags, uint32_t level) {
1531    // dirty is an out parameter and should not be recorded,
1532    // it matters only when replaying the display list
1533
1534    addOp(DisplayList::DrawDisplayList);
1535    addDisplayList(displayList);
1536    addInt(flags);
1537    return DrawGlInfo::kStatusDone;
1538}
1539
1540status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1541    addOp(DisplayList::DrawLayer);
1542    addInt((int) layer);
1543    addPoint(x, y);
1544    addPaint(paint);
1545    return DrawGlInfo::kStatusDone;
1546}
1547
1548status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
1549    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1550    uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
1551    addBitmap(bitmap);
1552    addPoint(left, top);
1553    addPaint(paint);
1554    addSkip(location);
1555    return DrawGlInfo::kStatusDone;
1556}
1557
1558status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
1559    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
1560    const mat4 transform(*matrix);
1561    transform.mapRect(r);
1562
1563    const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
1564    uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
1565    addBitmap(bitmap);
1566    addMatrix(matrix);
1567    addPaint(paint);
1568    addSkip(location);
1569    return DrawGlInfo::kStatusDone;
1570}
1571
1572status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1573        float srcRight, float srcBottom, float dstLeft, float dstTop,
1574        float dstRight, float dstBottom, SkPaint* paint) {
1575    const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
1576    uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
1577    addBitmap(bitmap);
1578    addBounds(srcLeft, srcTop, srcRight, srcBottom);
1579    addBounds(dstLeft, dstTop, dstRight, dstBottom);
1580    addPaint(paint);
1581    addSkip(location);
1582    return DrawGlInfo::kStatusDone;
1583}
1584
1585status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
1586        SkPaint* paint) {
1587    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1588    uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
1589    addBitmapData(bitmap);
1590    addPoint(left, top);
1591    addPaint(paint);
1592    addSkip(location);
1593    return DrawGlInfo::kStatusDone;
1594}
1595
1596status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1597        float* vertices, int* colors, SkPaint* paint) {
1598    addOp(DisplayList::DrawBitmapMesh);
1599    addBitmap(bitmap);
1600    addInt(meshWidth);
1601    addInt(meshHeight);
1602    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1603    if (colors) {
1604        addInt(1);
1605        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1606    } else {
1607        addInt(0);
1608    }
1609    addPaint(paint);
1610    return DrawGlInfo::kStatusDone;
1611}
1612
1613status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
1614        const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
1615        int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
1616    int alpha;
1617    SkXfermode::Mode mode;
1618    OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
1619
1620    const bool reject = quickReject(left, top, right, bottom);
1621    uint32_t* location = addOp(DisplayList::DrawPatch, reject);
1622    addBitmap(bitmap);
1623    addInts(xDivs, width);
1624    addInts(yDivs, height);
1625    addUInts(colors, numColors);
1626    addBounds(left, top, right, bottom);
1627    addInt(alpha);
1628    addInt(mode);
1629    addSkip(location);
1630    return DrawGlInfo::kStatusDone;
1631}
1632
1633status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1634    addOp(DisplayList::DrawColor);
1635    addInt(color);
1636    addInt(mode);
1637    return DrawGlInfo::kStatusDone;
1638}
1639
1640status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1641        SkPaint* paint) {
1642    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1643            quickReject(left, top, right, bottom);
1644    uint32_t* location = addOp(DisplayList::DrawRect, reject);
1645    addBounds(left, top, right, bottom);
1646    addPaint(paint);
1647    addSkip(location);
1648    return DrawGlInfo::kStatusDone;
1649}
1650
1651status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1652        float rx, float ry, SkPaint* paint) {
1653    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1654            quickReject(left, top, right, bottom);
1655    uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
1656    addBounds(left, top, right, bottom);
1657    addPoint(rx, ry);
1658    addPaint(paint);
1659    addSkip(location);
1660    return DrawGlInfo::kStatusDone;
1661}
1662
1663status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1664    addOp(DisplayList::DrawCircle);
1665    addPoint(x, y);
1666    addFloat(radius);
1667    addPaint(paint);
1668    return DrawGlInfo::kStatusDone;
1669}
1670
1671status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1672        SkPaint* paint) {
1673    addOp(DisplayList::DrawOval);
1674    addBounds(left, top, right, bottom);
1675    addPaint(paint);
1676    return DrawGlInfo::kStatusDone;
1677}
1678
1679status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1680        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1681    addOp(DisplayList::DrawArc);
1682    addBounds(left, top, right, bottom);
1683    addPoint(startAngle, sweepAngle);
1684    addInt(useCenter ? 1 : 0);
1685    addPaint(paint);
1686    return DrawGlInfo::kStatusDone;
1687}
1688
1689status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1690    float left, top, offset;
1691    uint32_t width, height;
1692    computePathBounds(path, paint, left, top, offset, width, height);
1693
1694    left -= offset;
1695    top -= offset;
1696
1697    const bool reject = quickReject(left, top, left + width, top + height);
1698    uint32_t* location = addOp(DisplayList::DrawPath, reject);
1699    addPath(path);
1700    addPaint(paint);
1701    addSkip(location);
1702    return DrawGlInfo::kStatusDone;
1703}
1704
1705status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1706    addOp(DisplayList::DrawLines);
1707    addFloats(points, count);
1708    addPaint(paint);
1709    return DrawGlInfo::kStatusDone;
1710}
1711
1712status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1713    addOp(DisplayList::DrawPoints);
1714    addFloats(points, count);
1715    addPaint(paint);
1716    return DrawGlInfo::kStatusDone;
1717}
1718
1719status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
1720        SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
1721    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1722    addOp(DisplayList::DrawTextOnPath);
1723    addText(text, bytesCount);
1724    addInt(count);
1725    addPath(path);
1726    addFloat(hOffset);
1727    addFloat(vOffset);
1728    paint->setAntiAlias(true);
1729    SkPaint* addedPaint = addPaint(paint);
1730    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
1731    fontRenderer.precache(addedPaint, text, count);
1732    return DrawGlInfo::kStatusDone;
1733}
1734
1735status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
1736        const float* positions, SkPaint* paint) {
1737    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1738    addOp(DisplayList::DrawPosText);
1739    addText(text, bytesCount);
1740    addInt(count);
1741    addFloats(positions, count * 2);
1742    paint->setAntiAlias(true);
1743    SkPaint* addedPaint = addPaint(paint);
1744    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
1745    fontRenderer.precache(addedPaint, text, count);
1746    return DrawGlInfo::kStatusDone;
1747}
1748
1749status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
1750        float x, float y, const float* positions, SkPaint* paint, float length) {
1751    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1752
1753    // TODO: We should probably make a copy of the paint instead of modifying
1754    //       it; modifying the paint will change its generationID the first
1755    //       time, which might impact caches. More investigation needed to
1756    //       see if it matters.
1757    //       If we make a copy, then drawTextDecorations() should *not* make
1758    //       its own copy as it does right now.
1759    // Beware: this needs Glyph encoding (already done on the Paint constructor)
1760    paint->setAntiAlias(true);
1761    if (length < 0.0f) length = paint->measureText(text, bytesCount);
1762
1763    bool reject = false;
1764    if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
1765        SkPaint::FontMetrics metrics;
1766        paint->getFontMetrics(&metrics, 0.0f);
1767        reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
1768    }
1769
1770    uint32_t* location = addOp(DisplayList::DrawText, reject);
1771    addText(text, bytesCount);
1772    addInt(count);
1773    addFloat(x);
1774    addFloat(y);
1775    addFloats(positions, count * 2);
1776    SkPaint* addedPaint = addPaint(paint);
1777    if (!reject) {
1778        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
1779        fontRenderer.precache(addedPaint, text, count);
1780    }
1781    addFloat(length);
1782    addSkip(location);
1783    return DrawGlInfo::kStatusDone;
1784}
1785
1786void DisplayListRenderer::resetShader() {
1787    addOp(DisplayList::ResetShader);
1788}
1789
1790void DisplayListRenderer::setupShader(SkiaShader* shader) {
1791    addOp(DisplayList::SetupShader);
1792    addShader(shader);
1793}
1794
1795void DisplayListRenderer::resetColorFilter() {
1796    addOp(DisplayList::ResetColorFilter);
1797}
1798
1799void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1800    addOp(DisplayList::SetupColorFilter);
1801    addColorFilter(filter);
1802}
1803
1804void DisplayListRenderer::resetShadow() {
1805    addOp(DisplayList::ResetShadow);
1806}
1807
1808void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1809    addOp(DisplayList::SetupShadow);
1810    addFloat(radius);
1811    addPoint(dx, dy);
1812    addInt(color);
1813}
1814
1815void DisplayListRenderer::resetPaintFilter() {
1816    addOp(DisplayList::ResetPaintFilter);
1817}
1818
1819void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
1820    addOp(DisplayList::SetupPaintFilter);
1821    addInt(clearBits);
1822    addInt(setBits);
1823}
1824
1825}; // namespace uirenderer
1826}; // namespace android
1827