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