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