DisplayListRenderer.cpp revision 58ecc204fbcacef34806290492384677a330d4d4
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    "DrawTextOnPath",
65    "DrawPosText",
66    "DrawText",
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
153    mTransformMatrix = NULL;
154    mTransformCamera = NULL;
155    mTransformMatrix3D = NULL;
156    mStaticMatrix = NULL;
157    mAnimationMatrix = NULL;
158
159    Caches& caches = Caches::getInstance();
160    caches.resourceCache.lock();
161
162    for (size_t i = 0; i < mBitmapResources.size(); i++) {
163        caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
164    }
165
166    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
167        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
168        caches.resourceCache.decrementRefcountLocked(bitmap);
169        caches.resourceCache.destructorLocked(bitmap);
170    }
171
172    for (size_t i = 0; i < mFilterResources.size(); i++) {
173        caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
174    }
175
176    for (size_t i = 0; i < mShaders.size(); i++) {
177        caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
178        caches.resourceCache.destructorLocked(mShaders.itemAt(i));
179    }
180
181    for (size_t i = 0; i < mSourcePaths.size(); i++) {
182        caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
183    }
184
185    caches.resourceCache.unlock();
186
187    for (size_t i = 0; i < mPaints.size(); i++) {
188        delete mPaints.itemAt(i);
189    }
190
191    for (size_t i = 0; i < mPaths.size(); i++) {
192        SkPath* path = mPaths.itemAt(i);
193        caches.pathCache.remove(path);
194        delete path;
195    }
196
197    for (size_t i = 0; i < mMatrices.size(); i++) {
198        delete mMatrices.itemAt(i);
199    }
200
201    mBitmapResources.clear();
202    mOwnedBitmapResources.clear();
203    mFilterResources.clear();
204    mShaders.clear();
205    mSourcePaths.clear();
206    mPaints.clear();
207    mPaths.clear();
208    mMatrices.clear();
209}
210
211void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
212    const SkWriter32& writer = recorder.writeStream();
213    init();
214
215    if (writer.size() == 0) {
216        return;
217    }
218
219    if (reusing) {
220        // re-using display list - clear out previous allocations
221        clearResources();
222    }
223    initProperties();
224
225    mSize = writer.size();
226    void* buffer = sk_malloc_throw(mSize);
227    writer.flatten(buffer);
228    mReader.setMemory(buffer, mSize);
229
230    Caches& caches = Caches::getInstance();
231    caches.resourceCache.lock();
232
233    const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
234    for (size_t i = 0; i < bitmapResources.size(); i++) {
235        SkBitmap* resource = bitmapResources.itemAt(i);
236        mBitmapResources.add(resource);
237        caches.resourceCache.incrementRefcountLocked(resource);
238    }
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                Layer* layer = (Layer*) getInt();
1016                float x = getFloat();
1017                float y = getFloat();
1018                SkPaint* paint = getPaint(renderer);
1019                if (mCaching) {
1020                    paint->setAlpha(mMultipliedAlpha);
1021                }
1022                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1023                        layer, x, y, paint);
1024                drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
1025            }
1026            break;
1027            case DrawBitmap: {
1028                SkBitmap* bitmap = getBitmap();
1029                float x = getFloat();
1030                float y = getFloat();
1031                SkPaint* paint = getPaint(renderer);
1032                if (mCaching) {
1033                    paint->setAlpha(mMultipliedAlpha);
1034                }
1035                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1036                        bitmap, x, y, paint);
1037                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1038            }
1039            break;
1040            case DrawBitmapMatrix: {
1041                SkBitmap* bitmap = getBitmap();
1042                SkMatrix* matrix = getMatrix();
1043                SkPaint* paint = getPaint(renderer);
1044                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
1045                        bitmap, matrix, paint);
1046                drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
1047            }
1048            break;
1049            case DrawBitmapRect: {
1050                SkBitmap* bitmap = getBitmap();
1051                float f1 = getFloat();
1052                float f2 = getFloat();
1053                float f3 = getFloat();
1054                float f4 = getFloat();
1055                float f5 = getFloat();
1056                float f6 = getFloat();
1057                float f7 = getFloat();
1058                float f8 = getFloat();
1059                SkPaint* paint = getPaint(renderer);
1060                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1061                        (char*) indent, OP_NAMES[op], bitmap,
1062                        f1, f2, f3, f4, f5, f6, f7, f8,paint);
1063                drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
1064            }
1065            break;
1066            case DrawBitmapData: {
1067                SkBitmap* bitmap = getBitmapData();
1068                float x = getFloat();
1069                float y = getFloat();
1070                SkPaint* paint = getPaint(renderer);
1071                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1072                        bitmap, x, y, paint);
1073                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1074            }
1075            break;
1076            case DrawBitmapMesh: {
1077                int32_t verticesCount = 0;
1078                uint32_t colorsCount = 0;
1079
1080                SkBitmap* bitmap = getBitmap();
1081                uint32_t meshWidth = getInt();
1082                uint32_t meshHeight = getInt();
1083                float* vertices = getFloats(verticesCount);
1084                bool hasColors = getInt();
1085                int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
1086                SkPaint* paint = getPaint(renderer);
1087
1088                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1089                drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
1090                        colors, paint);
1091            }
1092            break;
1093            case DrawPatch: {
1094                int32_t* xDivs = NULL;
1095                int32_t* yDivs = NULL;
1096                uint32_t* colors = NULL;
1097                uint32_t xDivsCount = 0;
1098                uint32_t yDivsCount = 0;
1099                int8_t numColors = 0;
1100
1101                SkBitmap* bitmap = getBitmap();
1102
1103                xDivs = getInts(xDivsCount);
1104                yDivs = getInts(yDivsCount);
1105                colors = getUInts(numColors);
1106
1107                float left = getFloat();
1108                float top = getFloat();
1109                float right = getFloat();
1110                float bottom = getFloat();
1111
1112                int alpha = getInt();
1113                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
1114
1115                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1116                drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
1117                        xDivsCount, yDivsCount, numColors, left, top, right, bottom,
1118                        alpha, mode);
1119            }
1120            break;
1121            case DrawColor: {
1122                int32_t color = getInt();
1123                int32_t xferMode = getInt();
1124                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
1125                drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
1126            }
1127            break;
1128            case DrawRect: {
1129                float f1 = getFloat();
1130                float f2 = getFloat();
1131                float f3 = getFloat();
1132                float f4 = getFloat();
1133                SkPaint* paint = getPaint(renderer);
1134                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1135                        f1, f2, f3, f4, paint);
1136                drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
1137            }
1138            break;
1139            case DrawRoundRect: {
1140                float f1 = getFloat();
1141                float f2 = getFloat();
1142                float f3 = getFloat();
1143                float f4 = getFloat();
1144                float f5 = getFloat();
1145                float f6 = getFloat();
1146                SkPaint* paint = getPaint(renderer);
1147                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1148                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
1149                drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
1150            }
1151            break;
1152            case DrawCircle: {
1153                float f1 = getFloat();
1154                float f2 = getFloat();
1155                float f3 = getFloat();
1156                SkPaint* paint = getPaint(renderer);
1157                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
1158                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
1159                drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
1160            }
1161            break;
1162            case DrawOval: {
1163                float f1 = getFloat();
1164                float f2 = getFloat();
1165                float f3 = getFloat();
1166                float f4 = getFloat();
1167                SkPaint* paint = getPaint(renderer);
1168                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
1169                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
1170                drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
1171            }
1172            break;
1173            case DrawArc: {
1174                float f1 = getFloat();
1175                float f2 = getFloat();
1176                float f3 = getFloat();
1177                float f4 = getFloat();
1178                float f5 = getFloat();
1179                float f6 = getFloat();
1180                int32_t i1 = getInt();
1181                SkPaint* paint = getPaint(renderer);
1182                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
1183                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
1184                drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
1185            }
1186            break;
1187            case DrawPath: {
1188                SkPath* path = getPath();
1189                SkPaint* paint = getPaint(renderer);
1190                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
1191                drawGlStatus |= renderer.drawPath(path, paint);
1192            }
1193            break;
1194            case DrawLines: {
1195                int32_t count = 0;
1196                float* points = getFloats(count);
1197                SkPaint* paint = getPaint(renderer);
1198                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1199                drawGlStatus |= renderer.drawLines(points, count, paint);
1200            }
1201            break;
1202            case DrawPoints: {
1203                int32_t count = 0;
1204                float* points = getFloats(count);
1205                SkPaint* paint = getPaint(renderer);
1206                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1207                drawGlStatus |= renderer.drawPoints(points, count, paint);
1208            }
1209            break;
1210            case DrawTextOnPath: {
1211                getText(&text);
1212                int32_t count = getInt();
1213                SkPath* path = getPath();
1214                float hOffset = getFloat();
1215                float vOffset = getFloat();
1216                SkPaint* paint = getPaint(renderer);
1217                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
1218                    text.text(), text.length(), count, paint);
1219                drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
1220                        hOffset, vOffset, paint);
1221            }
1222            break;
1223            case DrawPosText: {
1224                getText(&text);
1225                int32_t count = getInt();
1226                int32_t positionsCount = 0;
1227                float* positions = getFloats(positionsCount);
1228                SkPaint* paint = getPaint(renderer);
1229                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
1230                        OP_NAMES[op], text.text(), text.length(), count, paint);
1231                drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
1232                        positions, paint);
1233            }
1234            break;
1235            case DrawText: {
1236                getText(&text);
1237                int32_t count = getInt();
1238                float x = getFloat();
1239                float y = getFloat();
1240                int32_t positionsCount = 0;
1241                float* positions = getFloats(positionsCount);
1242                SkPaint* paint = getPaint(renderer);
1243                float length = getFloat();
1244                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
1245                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
1246                drawGlStatus |= renderer.drawText(text.text(), text.length(), count,
1247                        x, y, positions, paint, length);
1248            }
1249            break;
1250            case ResetShader: {
1251                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1252                renderer.resetShader();
1253            }
1254            break;
1255            case SetupShader: {
1256                SkiaShader* shader = getShader();
1257                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
1258                renderer.setupShader(shader);
1259            }
1260            break;
1261            case ResetColorFilter: {
1262                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1263                renderer.resetColorFilter();
1264            }
1265            break;
1266            case SetupColorFilter: {
1267                SkiaColorFilter *colorFilter = getColorFilter();
1268                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
1269                renderer.setupColorFilter(colorFilter);
1270            }
1271            break;
1272            case ResetShadow: {
1273                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1274                renderer.resetShadow();
1275            }
1276            break;
1277            case SetupShadow: {
1278                float radius = getFloat();
1279                float dx = getFloat();
1280                float dy = getFloat();
1281                int32_t color = getInt();
1282                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
1283                        radius, dx, dy, color);
1284                renderer.setupShadow(radius, dx, dy, color);
1285            }
1286            break;
1287            case ResetPaintFilter: {
1288                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1289                renderer.resetPaintFilter();
1290            }
1291            break;
1292            case SetupPaintFilter: {
1293                int32_t clearBits = getInt();
1294                int32_t setBits = getInt();
1295                DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
1296                        clearBits, setBits);
1297                renderer.setupPaintFilter(clearBits, setBits);
1298            }
1299            break;
1300            default:
1301                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
1302                        (char*) indent, OP_NAMES[op]);
1303                break;
1304        }
1305    }
1306
1307    DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
1308    renderer.restoreToCount(restoreTo);
1309    renderer.endMark();
1310
1311    DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
1312            drawGlStatus);
1313    return drawGlStatus;
1314}
1315
1316///////////////////////////////////////////////////////////////////////////////
1317// Base structure
1318///////////////////////////////////////////////////////////////////////////////
1319
1320DisplayListRenderer::DisplayListRenderer():
1321        mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE),
1322        mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
1323}
1324
1325DisplayListRenderer::~DisplayListRenderer() {
1326    reset();
1327}
1328
1329void DisplayListRenderer::reset() {
1330    mWriter.reset();
1331
1332    mCaches.resourceCache.lock();
1333
1334    for (size_t i = 0; i < mBitmapResources.size(); i++) {
1335        mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
1336    }
1337
1338    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
1339        mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
1340    }
1341
1342    for (size_t i = 0; i < mFilterResources.size(); i++) {
1343        mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
1344    }
1345
1346    for (size_t i = 0; i < mShaders.size(); i++) {
1347        mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
1348    }
1349
1350    for (size_t i = 0; i < mSourcePaths.size(); i++) {
1351        mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
1352    }
1353
1354    mCaches.resourceCache.unlock();
1355
1356    mBitmapResources.clear();
1357    mOwnedBitmapResources.clear();
1358    mFilterResources.clear();
1359    mSourcePaths.clear();
1360
1361    mShaders.clear();
1362    mShaderMap.clear();
1363
1364    mPaints.clear();
1365    mPaintMap.clear();
1366
1367    mPaths.clear();
1368    mPathMap.clear();
1369
1370    mMatrices.clear();
1371
1372    mHasDrawOps = false;
1373}
1374
1375///////////////////////////////////////////////////////////////////////////////
1376// Operations
1377///////////////////////////////////////////////////////////////////////////////
1378
1379DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
1380    if (!displayList) {
1381        displayList = new DisplayList(*this);
1382    } else {
1383        displayList->initFromDisplayListRenderer(*this, true);
1384    }
1385    displayList->setRenderable(mHasDrawOps);
1386    return displayList;
1387}
1388
1389bool DisplayListRenderer::isDeferred() {
1390    return true;
1391}
1392
1393void DisplayListRenderer::setViewport(int width, int height) {
1394    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
1395
1396    mWidth = width;
1397    mHeight = height;
1398}
1399
1400int DisplayListRenderer::prepareDirty(float left, float top,
1401        float right, float bottom, bool opaque) {
1402    mSnapshot = new Snapshot(mFirstSnapshot,
1403            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
1404    mSaveCount = 1;
1405    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
1406    mRestoreSaveCount = -1;
1407    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1408}
1409
1410void DisplayListRenderer::finish() {
1411    insertRestoreToCount();
1412    insertTranlate();
1413}
1414
1415void DisplayListRenderer::interrupt() {
1416}
1417
1418void DisplayListRenderer::resume() {
1419}
1420
1421status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
1422    // Ignore dirty during recording, it matters only when we replay
1423    addOp(DisplayList::DrawGLFunction);
1424    addInt((int) functor);
1425    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1426}
1427
1428int DisplayListRenderer::save(int flags) {
1429    addOp(DisplayList::Save);
1430    addInt(flags);
1431    return OpenGLRenderer::save(flags);
1432}
1433
1434void DisplayListRenderer::restore() {
1435    if (mRestoreSaveCount < 0) {
1436        restoreToCount(getSaveCount() - 1);
1437        return;
1438    }
1439
1440    mRestoreSaveCount--;
1441    insertTranlate();
1442    OpenGLRenderer::restore();
1443}
1444
1445void DisplayListRenderer::restoreToCount(int saveCount) {
1446    mRestoreSaveCount = saveCount;
1447    insertTranlate();
1448    OpenGLRenderer::restoreToCount(saveCount);
1449}
1450
1451int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1452        SkPaint* p, int flags) {
1453    addOp(DisplayList::SaveLayer);
1454    addBounds(left, top, right, bottom);
1455    addPaint(p);
1456    addInt(flags);
1457    return OpenGLRenderer::save(flags);
1458}
1459
1460int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1461        int alpha, int flags) {
1462    addOp(DisplayList::SaveLayerAlpha);
1463    addBounds(left, top, right, bottom);
1464    addInt(alpha);
1465    addInt(flags);
1466    return OpenGLRenderer::save(flags);
1467}
1468
1469void DisplayListRenderer::translate(float dx, float dy) {
1470    mHasTranslate = true;
1471    mTranslateX += dx;
1472    mTranslateY += dy;
1473    insertRestoreToCount();
1474    OpenGLRenderer::translate(dx, dy);
1475}
1476
1477void DisplayListRenderer::rotate(float degrees) {
1478    addOp(DisplayList::Rotate);
1479    addFloat(degrees);
1480    OpenGLRenderer::rotate(degrees);
1481}
1482
1483void DisplayListRenderer::scale(float sx, float sy) {
1484    addOp(DisplayList::Scale);
1485    addPoint(sx, sy);
1486    OpenGLRenderer::scale(sx, sy);
1487}
1488
1489void DisplayListRenderer::skew(float sx, float sy) {
1490    addOp(DisplayList::Skew);
1491    addPoint(sx, sy);
1492    OpenGLRenderer::skew(sx, sy);
1493}
1494
1495void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1496    addOp(DisplayList::SetMatrix);
1497    addMatrix(matrix);
1498    OpenGLRenderer::setMatrix(matrix);
1499}
1500
1501void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1502    addOp(DisplayList::ConcatMatrix);
1503    addMatrix(matrix);
1504    OpenGLRenderer::concatMatrix(matrix);
1505}
1506
1507bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1508        SkRegion::Op op) {
1509    addOp(DisplayList::ClipRect);
1510    addBounds(left, top, right, bottom);
1511    addInt(op);
1512    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1513}
1514
1515status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1516        Rect& dirty, int32_t flags, uint32_t level) {
1517    // dirty is an out parameter and should not be recorded,
1518    // it matters only when replaying the display list
1519
1520    addOp(DisplayList::DrawDisplayList);
1521    addDisplayList(displayList);
1522    addInt(flags);
1523    return DrawGlInfo::kStatusDone;
1524}
1525
1526status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1527    addOp(DisplayList::DrawLayer);
1528    addInt((int) layer);
1529    addPoint(x, y);
1530    addPaint(paint);
1531    return DrawGlInfo::kStatusDone;
1532}
1533
1534status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
1535    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1536    uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
1537    addBitmap(bitmap);
1538    addPoint(left, top);
1539    addPaint(paint);
1540    addSkip(location);
1541    return DrawGlInfo::kStatusDone;
1542}
1543
1544status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
1545    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
1546    const mat4 transform(*matrix);
1547    transform.mapRect(r);
1548
1549    const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
1550    uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
1551    addBitmap(bitmap);
1552    addMatrix(matrix);
1553    addPaint(paint);
1554    addSkip(location);
1555    return DrawGlInfo::kStatusDone;
1556}
1557
1558status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1559        float srcRight, float srcBottom, float dstLeft, float dstTop,
1560        float dstRight, float dstBottom, SkPaint* paint) {
1561    const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
1562    uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
1563    addBitmap(bitmap);
1564    addBounds(srcLeft, srcTop, srcRight, srcBottom);
1565    addBounds(dstLeft, dstTop, dstRight, dstBottom);
1566    addPaint(paint);
1567    addSkip(location);
1568    return DrawGlInfo::kStatusDone;
1569}
1570
1571status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
1572        SkPaint* paint) {
1573    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1574    uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
1575    addBitmapData(bitmap);
1576    addPoint(left, top);
1577    addPaint(paint);
1578    addSkip(location);
1579    return DrawGlInfo::kStatusDone;
1580}
1581
1582status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1583        float* vertices, int* colors, SkPaint* paint) {
1584    addOp(DisplayList::DrawBitmapMesh);
1585    addBitmap(bitmap);
1586    addInt(meshWidth);
1587    addInt(meshHeight);
1588    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1589    if (colors) {
1590        addInt(1);
1591        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1592    } else {
1593        addInt(0);
1594    }
1595    addPaint(paint);
1596    return DrawGlInfo::kStatusDone;
1597}
1598
1599status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
1600        const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
1601        int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
1602    int alpha;
1603    SkXfermode::Mode mode;
1604    OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
1605
1606    const bool reject = quickReject(left, top, right, bottom);
1607    uint32_t* location = addOp(DisplayList::DrawPatch, reject);
1608    addBitmap(bitmap);
1609    addInts(xDivs, width);
1610    addInts(yDivs, height);
1611    addUInts(colors, numColors);
1612    addBounds(left, top, right, bottom);
1613    addInt(alpha);
1614    addInt(mode);
1615    addSkip(location);
1616    return DrawGlInfo::kStatusDone;
1617}
1618
1619status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1620    addOp(DisplayList::DrawColor);
1621    addInt(color);
1622    addInt(mode);
1623    return DrawGlInfo::kStatusDone;
1624}
1625
1626status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1627        SkPaint* paint) {
1628    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1629            quickReject(left, top, right, bottom);
1630    uint32_t* location = addOp(DisplayList::DrawRect, reject);
1631    addBounds(left, top, right, bottom);
1632    addPaint(paint);
1633    addSkip(location);
1634    return DrawGlInfo::kStatusDone;
1635}
1636
1637status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1638        float rx, float ry, SkPaint* paint) {
1639    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1640            quickReject(left, top, right, bottom);
1641    uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
1642    addBounds(left, top, right, bottom);
1643    addPoint(rx, ry);
1644    addPaint(paint);
1645    addSkip(location);
1646    return DrawGlInfo::kStatusDone;
1647}
1648
1649status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1650    addOp(DisplayList::DrawCircle);
1651    addPoint(x, y);
1652    addFloat(radius);
1653    addPaint(paint);
1654    return DrawGlInfo::kStatusDone;
1655}
1656
1657status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1658        SkPaint* paint) {
1659    addOp(DisplayList::DrawOval);
1660    addBounds(left, top, right, bottom);
1661    addPaint(paint);
1662    return DrawGlInfo::kStatusDone;
1663}
1664
1665status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1666        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1667    addOp(DisplayList::DrawArc);
1668    addBounds(left, top, right, bottom);
1669    addPoint(startAngle, sweepAngle);
1670    addInt(useCenter ? 1 : 0);
1671    addPaint(paint);
1672    return DrawGlInfo::kStatusDone;
1673}
1674
1675status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1676    float left, top, offset;
1677    uint32_t width, height;
1678    computePathBounds(path, paint, left, top, offset, width, height);
1679
1680    left -= offset;
1681    top -= offset;
1682
1683    const bool reject = quickReject(left, top, left + width, top + height);
1684    uint32_t* location = addOp(DisplayList::DrawPath, reject);
1685    addPath(path);
1686    addPaint(paint);
1687    addSkip(location);
1688    return DrawGlInfo::kStatusDone;
1689}
1690
1691status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1692    addOp(DisplayList::DrawLines);
1693    addFloats(points, count);
1694    addPaint(paint);
1695    return DrawGlInfo::kStatusDone;
1696}
1697
1698status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1699    addOp(DisplayList::DrawPoints);
1700    addFloats(points, count);
1701    addPaint(paint);
1702    return DrawGlInfo::kStatusDone;
1703}
1704
1705status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
1706        SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
1707    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1708    addOp(DisplayList::DrawTextOnPath);
1709    addText(text, bytesCount);
1710    addInt(count);
1711    addPath(path);
1712    addFloat(hOffset);
1713    addFloat(vOffset);
1714    paint->setAntiAlias(true);
1715    SkPaint* addedPaint = addPaint(paint);
1716    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
1717    fontRenderer.precache(addedPaint, text, count);
1718    return DrawGlInfo::kStatusDone;
1719}
1720
1721status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
1722        const float* positions, SkPaint* paint) {
1723    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1724    addOp(DisplayList::DrawPosText);
1725    addText(text, bytesCount);
1726    addInt(count);
1727    addFloats(positions, count * 2);
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::drawText(const char* text, int bytesCount, int count,
1736        float x, float y, const float* positions, SkPaint* paint, float length) {
1737    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1738
1739    // TODO: We should probably make a copy of the paint instead of modifying
1740    //       it; modifying the paint will change its generationID the first
1741    //       time, which might impact caches. More investigation needed to
1742    //       see if it matters.
1743    //       If we make a copy, then drawTextDecorations() should *not* make
1744    //       its own copy as it does right now.
1745    // Beware: this needs Glyph encoding (already done on the Paint constructor)
1746    paint->setAntiAlias(true);
1747    if (length < 0.0f) length = paint->measureText(text, bytesCount);
1748
1749    bool reject = false;
1750    if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
1751        SkPaint::FontMetrics metrics;
1752        paint->getFontMetrics(&metrics, 0.0f);
1753        reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
1754    }
1755
1756    uint32_t* location = addOp(DisplayList::DrawText, reject);
1757    addText(text, bytesCount);
1758    addInt(count);
1759    addFloat(x);
1760    addFloat(y);
1761    addFloats(positions, count * 2);
1762    SkPaint* addedPaint = addPaint(paint);
1763    if (!reject) {
1764        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
1765        fontRenderer.precache(addedPaint, text, count);
1766    }
1767    addFloat(length);
1768    addSkip(location);
1769    return DrawGlInfo::kStatusDone;
1770}
1771
1772void DisplayListRenderer::resetShader() {
1773    addOp(DisplayList::ResetShader);
1774}
1775
1776void DisplayListRenderer::setupShader(SkiaShader* shader) {
1777    addOp(DisplayList::SetupShader);
1778    addShader(shader);
1779}
1780
1781void DisplayListRenderer::resetColorFilter() {
1782    addOp(DisplayList::ResetColorFilter);
1783}
1784
1785void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1786    addOp(DisplayList::SetupColorFilter);
1787    addColorFilter(filter);
1788}
1789
1790void DisplayListRenderer::resetShadow() {
1791    addOp(DisplayList::ResetShadow);
1792}
1793
1794void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1795    addOp(DisplayList::SetupShadow);
1796    addFloat(radius);
1797    addPoint(dx, dy);
1798    addInt(color);
1799}
1800
1801void DisplayListRenderer::resetPaintFilter() {
1802    addOp(DisplayList::ResetPaintFilter);
1803}
1804
1805void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
1806    addOp(DisplayList::SetupPaintFilter);
1807    addInt(clearBits);
1808    addInt(setBits);
1809}
1810
1811}; // namespace uirenderer
1812}; // namespace android
1813