DisplayListRenderer.cpp revision eb9a5367e8f0e970db8509ffb2584f5376bc62ed
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
20#include "DisplayListLogBuffer.h"
21#include "DisplayListRenderer.h"
22#include <utils/String8.h>
23#include "Caches.h"
24
25namespace android {
26namespace uirenderer {
27
28
29///////////////////////////////////////////////////////////////////////////////
30// Display list
31///////////////////////////////////////////////////////////////////////////////
32
33const char* DisplayList::OP_NAMES[] = {
34    "Save",
35    "Restore",
36    "RestoreToCount",
37    "SaveLayer",
38    "SaveLayerAlpha",
39    "Translate",
40    "Rotate",
41    "Scale",
42    "Skew",
43    "SetMatrix",
44    "ConcatMatrix",
45    "ClipRect",
46    "DrawDisplayList",
47    "DrawLayer",
48    "DrawBitmap",
49    "DrawBitmapMatrix",
50    "DrawBitmapRect",
51    "DrawBitmapMesh",
52    "DrawPatch",
53    "DrawColor",
54    "DrawRect",
55    "DrawRoundRect",
56    "DrawCircle",
57    "DrawOval",
58    "DrawArc",
59    "DrawPath",
60    "DrawLines",
61    "DrawPoints",
62    "DrawText",
63    "DrawPosText",
64    "ResetShader",
65    "SetupShader",
66    "ResetColorFilter",
67    "SetupColorFilter",
68    "ResetShadow",
69    "SetupShadow",
70    "DrawGLFunction"
71};
72
73void DisplayList::outputLogBuffer(int fd) {
74    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
75    if (logBuffer.isEmpty()) {
76        return;
77    }
78
79    FILE *file = fdopen(fd, "a");
80
81    fprintf(file, "\nRecent DisplayList operations\n");
82    logBuffer.outputCommands(file, OP_NAMES);
83
84    String8 cachesLog;
85    Caches::getInstance().dumpMemoryUsage(cachesLog);
86    fprintf(file, "\nCaches:\n%s", cachesLog.string());
87    fprintf(file, "\n");
88
89    fflush(file);
90}
91
92DisplayList::DisplayList(const DisplayListRenderer& recorder) {
93    initFromDisplayListRenderer(recorder);
94}
95
96DisplayList::~DisplayList() {
97    clearResources();
98}
99
100void DisplayList::clearResources() {
101    sk_free((void*) mReader.base());
102
103    Caches& caches = Caches::getInstance();
104
105    for (size_t i = 0; i < mBitmapResources.size(); i++) {
106        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
107    }
108    mBitmapResources.clear();
109
110    for (size_t i = 0; i < mFilterResources.size(); i++) {
111        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
112    }
113    mFilterResources.clear();
114
115    for (size_t i = 0; i < mShaders.size(); i++) {
116        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
117        caches.resourceCache.destructor(mShaders.itemAt(i));
118    }
119    mShaders.clear();
120
121    for (size_t i = 0; i < mPaints.size(); i++) {
122        delete mPaints.itemAt(i);
123    }
124    mPaints.clear();
125
126    for (size_t i = 0; i < mPaths.size(); i++) {
127        SkPath* path = mPaths.itemAt(i);
128        caches.pathCache.remove(path);
129        delete path;
130    }
131    mPaths.clear();
132
133    for (size_t i = 0; i < mMatrices.size(); i++) {
134        delete mMatrices.itemAt(i);
135    }
136    mMatrices.clear();
137}
138
139void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
140    const SkWriter32& writer = recorder.writeStream();
141    init();
142
143    if (writer.size() == 0) {
144        return;
145    }
146
147    if (reusing) {
148        // re-using display list - clear out previous allocations
149        clearResources();
150    }
151
152    mSize = writer.size();
153    void* buffer = sk_malloc_throw(mSize);
154    writer.flatten(buffer);
155    mReader.setMemory(buffer, mSize);
156
157    Caches& caches = Caches::getInstance();
158
159    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
160    for (size_t i = 0; i < bitmapResources.size(); i++) {
161        SkBitmap* resource = bitmapResources.itemAt(i);
162        mBitmapResources.add(resource);
163        caches.resourceCache.incrementRefcount(resource);
164    }
165
166    const Vector<SkiaColorFilter*> &filterResources = recorder.getFilterResources();
167    for (size_t i = 0; i < filterResources.size(); i++) {
168        SkiaColorFilter* resource = filterResources.itemAt(i);
169        mFilterResources.add(resource);
170        caches.resourceCache.incrementRefcount(resource);
171    }
172
173    const Vector<SkiaShader*> &shaders = recorder.getShaders();
174    for (size_t i = 0; i < shaders.size(); i++) {
175        SkiaShader* resource = shaders.itemAt(i);
176        mShaders.add(resource);
177        caches.resourceCache.incrementRefcount(resource);
178    }
179
180    const Vector<SkPaint*> &paints = recorder.getPaints();
181    for (size_t i = 0; i < paints.size(); i++) {
182        mPaints.add(paints.itemAt(i));
183    }
184
185    const Vector<SkPath*> &paths = recorder.getPaths();
186    for (size_t i = 0; i < paths.size(); i++) {
187        mPaths.add(paths.itemAt(i));
188    }
189
190    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
191    for (size_t i = 0; i < matrices.size(); i++) {
192        mMatrices.add(matrices.itemAt(i));
193    }
194}
195
196void DisplayList::init() {
197    mSize = 0;
198    mIsRenderable = true;
199}
200
201size_t DisplayList::getSize() {
202    return mSize;
203}
204
205/**
206 * This function is a simplified version of replay(), where we simply retrieve and log the
207 * display list. This function should remain in sync with the replay() function.
208 */
209void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
210    TextContainer text;
211
212    uint32_t count = (level + 1) * 2;
213    char indent[count + 1];
214    for (uint32_t i = 0; i < count; i++) {
215        indent[i] = ' ';
216    }
217    indent[count] = '\0';
218    ALOGD("%sStart display list (%p)", (char*) indent + 2, this);
219
220    int saveCount = renderer.getSaveCount() - 1;
221
222    mReader.rewind();
223
224    while (!mReader.eof()) {
225        int op = mReader.readInt();
226
227        switch (op) {
228            case DrawGLFunction: {
229                Functor *functor = (Functor *) getInt();
230                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
231            }
232            break;
233            case Save: {
234                int rendererNum = getInt();
235                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
236            }
237            break;
238            case Restore: {
239                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
240            }
241            break;
242            case RestoreToCount: {
243                int restoreCount = saveCount + getInt();
244                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
245            }
246            break;
247            case SaveLayer: {
248                float f1 = getFloat();
249                float f2 = getFloat();
250                float f3 = getFloat();
251                float f4 = getFloat();
252                SkPaint* paint = getPaint();
253                int flags = getInt();
254                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
255                    OP_NAMES[op], f1, f2, f3, f4, paint, flags);
256            }
257            break;
258            case SaveLayerAlpha: {
259                float f1 = getFloat();
260                float f2 = getFloat();
261                float f3 = getFloat();
262                float f4 = getFloat();
263                int alpha = getInt();
264                int flags = getInt();
265                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
266                    OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
267            }
268            break;
269            case Translate: {
270                float f1 = getFloat();
271                float f2 = getFloat();
272                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
273            }
274            break;
275            case Rotate: {
276                float rotation = getFloat();
277                ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
278            }
279            break;
280            case Scale: {
281                float sx = getFloat();
282                float sy = getFloat();
283                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
284            }
285            break;
286            case Skew: {
287                float sx = getFloat();
288                float sy = getFloat();
289                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
290            }
291            break;
292            case SetMatrix: {
293                SkMatrix* matrix = getMatrix();
294                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
295            }
296            break;
297            case ConcatMatrix: {
298                SkMatrix* matrix = getMatrix();
299                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
300            }
301            break;
302            case ClipRect: {
303                float f1 = getFloat();
304                float f2 = getFloat();
305                float f3 = getFloat();
306                float f4 = getFloat();
307                int regionOp = getInt();
308                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
309                    f1, f2, f3, f4, regionOp);
310            }
311            break;
312            case DrawDisplayList: {
313                DisplayList* displayList = getDisplayList();
314                uint32_t width = getUInt();
315                uint32_t height = getUInt();
316                ALOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
317                    displayList, width, height, level + 1);
318                renderer.outputDisplayList(displayList, level + 1);
319            }
320            break;
321            case DrawLayer: {
322                Layer* layer = (Layer*) getInt();
323                float x = getFloat();
324                float y = getFloat();
325                SkPaint* paint = getPaint();
326                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
327                    layer, x, y, paint);
328            }
329            break;
330            case DrawBitmap: {
331                SkBitmap* bitmap = getBitmap();
332                float x = getFloat();
333                float y = getFloat();
334                SkPaint* paint = getPaint();
335                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
336                    bitmap, x, y, paint);
337            }
338            break;
339            case DrawBitmapMatrix: {
340                SkBitmap* bitmap = getBitmap();
341                SkMatrix* matrix = getMatrix();
342                SkPaint* paint = getPaint();
343                ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
344                    bitmap, matrix, paint);
345            }
346            break;
347            case DrawBitmapRect: {
348                SkBitmap* bitmap = getBitmap();
349                float f1 = getFloat();
350                float f2 = getFloat();
351                float f3 = getFloat();
352                float f4 = getFloat();
353                float f5 = getFloat();
354                float f6 = getFloat();
355                float f7 = getFloat();
356                float f8 = getFloat();
357                SkPaint* paint = getPaint();
358                ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
359                    (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
360            }
361            break;
362            case DrawBitmapMesh: {
363                int verticesCount = 0;
364                uint32_t colorsCount = 0;
365                SkBitmap* bitmap = getBitmap();
366                uint32_t meshWidth = getInt();
367                uint32_t meshHeight = getInt();
368                float* vertices = getFloats(verticesCount);
369                bool hasColors = getInt();
370                int* colors = hasColors ? getInts(colorsCount) : NULL;
371                SkPaint* paint = getPaint();
372                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
373            }
374            break;
375            case DrawPatch: {
376                int32_t* xDivs = NULL;
377                int32_t* yDivs = NULL;
378                uint32_t* colors = NULL;
379                uint32_t xDivsCount = 0;
380                uint32_t yDivsCount = 0;
381                int8_t numColors = 0;
382                SkBitmap* bitmap = getBitmap();
383                xDivs = getInts(xDivsCount);
384                yDivs = getInts(yDivsCount);
385                colors = getUInts(numColors);
386                float left = getFloat();
387                float top = getFloat();
388                float right = getFloat();
389                float bottom = getFloat();
390                SkPaint* paint = getPaint();
391                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
392                        left, top, right, bottom);
393            }
394            break;
395            case DrawColor: {
396                int color = getInt();
397                int xferMode = getInt();
398                ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
399            }
400            break;
401            case DrawRect: {
402                float f1 = getFloat();
403                float f2 = getFloat();
404                float f3 = getFloat();
405                float f4 = getFloat();
406                SkPaint* paint = getPaint();
407                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
408                    f1, f2, f3, f4, paint);
409            }
410            break;
411            case DrawRoundRect: {
412                float f1 = getFloat();
413                float f2 = getFloat();
414                float f3 = getFloat();
415                float f4 = getFloat();
416                float f5 = getFloat();
417                float f6 = getFloat();
418                SkPaint* paint = getPaint();
419                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
420                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
421            }
422            break;
423            case DrawCircle: {
424                float f1 = getFloat();
425                float f2 = getFloat();
426                float f3 = getFloat();
427                SkPaint* paint = getPaint();
428                ALOGD("%s%s %.2f, %.2f, %.2f, %p",
429                    (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
430            }
431            break;
432            case DrawOval: {
433                float f1 = getFloat();
434                float f2 = getFloat();
435                float f3 = getFloat();
436                float f4 = getFloat();
437                SkPaint* paint = getPaint();
438                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
439                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
440            }
441            break;
442            case DrawArc: {
443                float f1 = getFloat();
444                float f2 = getFloat();
445                float f3 = getFloat();
446                float f4 = getFloat();
447                float f5 = getFloat();
448                float f6 = getFloat();
449                int i1 = getInt();
450                SkPaint* paint = getPaint();
451                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
452                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
453            }
454            break;
455            case DrawPath: {
456                SkPath* path = getPath();
457                SkPaint* paint = getPaint();
458                ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
459            }
460            break;
461            case DrawLines: {
462                int count = 0;
463                float* points = getFloats(count);
464                SkPaint* paint = getPaint();
465                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
466            }
467            break;
468            case DrawPoints: {
469                int count = 0;
470                float* points = getFloats(count);
471                SkPaint* paint = getPaint();
472                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
473            }
474            break;
475            case DrawText: {
476                getText(&text);
477                int count = getInt();
478                float x = getFloat();
479                float y = getFloat();
480                SkPaint* paint = getPaint();
481                float length = getFloat();
482                ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
483                    text.text(), text.length(), count, x, y, paint, length);
484            }
485            break;
486            case DrawPosText: {
487                getText(&text);
488                int count = getInt();
489                int positionsCount = 0;
490                float* positions = getFloats(positionsCount);
491                SkPaint* paint = getPaint();
492                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
493                    text.text(), text.length(), count, paint);
494            }
495            case ResetShader: {
496                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
497            }
498            break;
499            case SetupShader: {
500                SkiaShader* shader = getShader();
501                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
502            }
503            break;
504            case ResetColorFilter: {
505                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
506            }
507            break;
508            case SetupColorFilter: {
509                SkiaColorFilter *colorFilter = getColorFilter();
510                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
511            }
512            break;
513            case ResetShadow: {
514                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
515            }
516            break;
517            case SetupShadow: {
518                float radius = getFloat();
519                float dx = getFloat();
520                float dy = getFloat();
521                int color = getInt();
522                ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
523                    radius, dx, dy, color);
524            }
525            break;
526            default:
527                ALOGD("Display List error: op not handled: %s%s",
528                    (char*) indent, OP_NAMES[op]);
529                break;
530        }
531    }
532
533    ALOGD("%sDone", (char*) indent + 2);
534}
535
536/**
537 * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
538 * in the output() function, since that function processes the same list of opcodes for the
539 * purposes of logging display list info for a given view.
540 */
541bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) {
542    bool needsInvalidate = false;
543    TextContainer text;
544    mReader.rewind();
545
546#if DEBUG_DISPLAY_LIST
547    uint32_t count = (level + 1) * 2;
548    char indent[count + 1];
549    for (uint32_t i = 0; i < count; i++) {
550        indent[i] = ' ';
551    }
552    indent[count] = '\0';
553    DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this);
554#endif
555
556    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
557    int saveCount = renderer.getSaveCount() - 1;
558    while (!mReader.eof()) {
559        int op = mReader.readInt();
560        logBuffer.writeCommand(level, op);
561
562        switch (op) {
563            case DrawGLFunction: {
564                Functor *functor = (Functor *) getInt();
565                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
566                needsInvalidate |= renderer.callDrawGLFunction(functor, dirty);
567            }
568            break;
569            case Save: {
570                int rendererNum = getInt();
571                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
572                renderer.save(rendererNum);
573            }
574            break;
575            case Restore: {
576                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
577                renderer.restore();
578            }
579            break;
580            case RestoreToCount: {
581                int restoreCount = saveCount + getInt();
582                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
583                renderer.restoreToCount(restoreCount);
584            }
585            break;
586            case SaveLayer: {
587                float f1 = getFloat();
588                float f2 = getFloat();
589                float f3 = getFloat();
590                float f4 = getFloat();
591                SkPaint* paint = getPaint();
592                int flags = getInt();
593                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
594                    OP_NAMES[op], f1, f2, f3, f4, paint, flags);
595                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
596            }
597            break;
598            case SaveLayerAlpha: {
599                float f1 = getFloat();
600                float f2 = getFloat();
601                float f3 = getFloat();
602                float f4 = getFloat();
603                int alpha = getInt();
604                int flags = getInt();
605                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
606                    OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
607                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
608            }
609            break;
610            case Translate: {
611                float f1 = getFloat();
612                float f2 = getFloat();
613                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
614                renderer.translate(f1, f2);
615            }
616            break;
617            case Rotate: {
618                float rotation = getFloat();
619                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
620                renderer.rotate(rotation);
621            }
622            break;
623            case Scale: {
624                float sx = getFloat();
625                float sy = getFloat();
626                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
627                renderer.scale(sx, sy);
628            }
629            break;
630            case Skew: {
631                float sx = getFloat();
632                float sy = getFloat();
633                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
634                renderer.skew(sx, sy);
635            }
636            break;
637            case SetMatrix: {
638                SkMatrix* matrix = getMatrix();
639                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
640                renderer.setMatrix(matrix);
641            }
642            break;
643            case ConcatMatrix: {
644                SkMatrix* matrix = getMatrix();
645                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
646                renderer.concatMatrix(matrix);
647            }
648            break;
649            case ClipRect: {
650                float f1 = getFloat();
651                float f2 = getFloat();
652                float f3 = getFloat();
653                float f4 = getFloat();
654                int regionOp = getInt();
655                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
656                    f1, f2, f3, f4, regionOp);
657                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
658            }
659            break;
660            case DrawDisplayList: {
661                DisplayList* displayList = getDisplayList();
662                uint32_t width = getUInt();
663                uint32_t height = getUInt();
664                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
665                    displayList, width, height, level + 1);
666                needsInvalidate |= renderer.drawDisplayList(displayList, width, height,
667                        dirty, level + 1);
668            }
669            break;
670            case DrawLayer: {
671                Layer* layer = (Layer*) getInt();
672                float x = getFloat();
673                float y = getFloat();
674                SkPaint* paint = getPaint();
675                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
676                    layer, x, y, paint);
677                renderer.drawLayer(layer, x, y, paint);
678            }
679            break;
680            case DrawBitmap: {
681                SkBitmap* bitmap = getBitmap();
682                float x = getFloat();
683                float y = getFloat();
684                SkPaint* paint = getPaint();
685                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
686                    bitmap, x, y, paint);
687                renderer.drawBitmap(bitmap, x, y, paint);
688            }
689            break;
690            case DrawBitmapMatrix: {
691                SkBitmap* bitmap = getBitmap();
692                SkMatrix* matrix = getMatrix();
693                SkPaint* paint = getPaint();
694                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
695                    bitmap, matrix, paint);
696                renderer.drawBitmap(bitmap, matrix, paint);
697            }
698            break;
699            case DrawBitmapRect: {
700                SkBitmap* bitmap = getBitmap();
701                float f1 = getFloat();
702                float f2 = getFloat();
703                float f3 = getFloat();
704                float f4 = getFloat();
705                float f5 = getFloat();
706                float f6 = getFloat();
707                float f7 = getFloat();
708                float f8 = getFloat();
709                SkPaint* paint = getPaint();
710                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
711                    (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
712                renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
713            }
714            break;
715            case DrawBitmapMesh: {
716                int verticesCount = 0;
717                uint32_t colorsCount = 0;
718
719                SkBitmap* bitmap = getBitmap();
720                uint32_t meshWidth = getInt();
721                uint32_t meshHeight = getInt();
722                float* vertices = getFloats(verticesCount);
723                bool hasColors = getInt();
724                int* colors = hasColors ? getInts(colorsCount) : NULL;
725                SkPaint* paint = getPaint();
726
727                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
728                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, paint);
729            }
730            break;
731            case DrawPatch: {
732                int32_t* xDivs = NULL;
733                int32_t* yDivs = NULL;
734                uint32_t* colors = NULL;
735                uint32_t xDivsCount = 0;
736                uint32_t yDivsCount = 0;
737                int8_t numColors = 0;
738
739                SkBitmap* bitmap = getBitmap();
740
741                xDivs = getInts(xDivsCount);
742                yDivs = getInts(yDivsCount);
743                colors = getUInts(numColors);
744
745                float left = getFloat();
746                float top = getFloat();
747                float right = getFloat();
748                float bottom = getFloat();
749                SkPaint* paint = getPaint();
750
751                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
752                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
753                        numColors, left, top, right, bottom, paint);
754            }
755            break;
756            case DrawColor: {
757                int color = getInt();
758                int xferMode = getInt();
759                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
760                renderer.drawColor(color, (SkXfermode::Mode) xferMode);
761            }
762            break;
763            case DrawRect: {
764                float f1 = getFloat();
765                float f2 = getFloat();
766                float f3 = getFloat();
767                float f4 = getFloat();
768                SkPaint* paint = getPaint();
769                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
770                    f1, f2, f3, f4, paint);
771                renderer.drawRect(f1, f2, f3, f4, paint);
772            }
773            break;
774            case DrawRoundRect: {
775                float f1 = getFloat();
776                float f2 = getFloat();
777                float f3 = getFloat();
778                float f4 = getFloat();
779                float f5 = getFloat();
780                float f6 = getFloat();
781                SkPaint* paint = getPaint();
782                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
783                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
784                renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
785            }
786            break;
787            case DrawCircle: {
788                float f1 = getFloat();
789                float f2 = getFloat();
790                float f3 = getFloat();
791                SkPaint* paint = getPaint();
792                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
793                    (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
794                renderer.drawCircle(f1, f2, f3, paint);
795            }
796            break;
797            case DrawOval: {
798                float f1 = getFloat();
799                float f2 = getFloat();
800                float f3 = getFloat();
801                float f4 = getFloat();
802                SkPaint* paint = getPaint();
803                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
804                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
805                renderer.drawOval(f1, f2, f3, f4, paint);
806            }
807            break;
808            case DrawArc: {
809                float f1 = getFloat();
810                float f2 = getFloat();
811                float f3 = getFloat();
812                float f4 = getFloat();
813                float f5 = getFloat();
814                float f6 = getFloat();
815                int i1 = getInt();
816                SkPaint* paint = getPaint();
817                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
818                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
819                renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
820            }
821            break;
822            case DrawPath: {
823                SkPath* path = getPath();
824                SkPaint* paint = getPaint();
825                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
826                renderer.drawPath(path, paint);
827            }
828            break;
829            case DrawLines: {
830                int count = 0;
831                float* points = getFloats(count);
832                SkPaint* paint = getPaint();
833                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
834                renderer.drawLines(points, count, paint);
835            }
836            break;
837            case DrawPoints: {
838                int count = 0;
839                float* points = getFloats(count);
840                SkPaint* paint = getPaint();
841                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
842                renderer.drawPoints(points, count, paint);
843            }
844            break;
845            case DrawText: {
846                getText(&text);
847                int count = getInt();
848                float x = getFloat();
849                float y = getFloat();
850                SkPaint* paint = getPaint();
851                float length = getFloat();
852                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
853                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
854                renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
855            }
856            break;
857            case DrawPosText: {
858                getText(&text);
859                int count = getInt();
860                int positionsCount = 0;
861                float* positions = getFloats(positionsCount);
862                SkPaint* paint = getPaint();
863                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
864                        OP_NAMES[op], text.text(), text.length(), count, paint);
865                renderer.drawPosText(text.text(), text.length(), count, positions, paint);
866            }
867            break;
868            case ResetShader: {
869                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
870                renderer.resetShader();
871            }
872            break;
873            case SetupShader: {
874                SkiaShader* shader = getShader();
875                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
876                renderer.setupShader(shader);
877            }
878            break;
879            case ResetColorFilter: {
880                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
881                renderer.resetColorFilter();
882            }
883            break;
884            case SetupColorFilter: {
885                SkiaColorFilter *colorFilter = getColorFilter();
886                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
887                renderer.setupColorFilter(colorFilter);
888            }
889            break;
890            case ResetShadow: {
891                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
892                renderer.resetShadow();
893            }
894            break;
895            case SetupShadow: {
896                float radius = getFloat();
897                float dx = getFloat();
898                float dy = getFloat();
899                int color = getInt();
900                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
901                    radius, dx, dy, color);
902                renderer.setupShadow(radius, dx, dy, color);
903            }
904            break;
905            default:
906                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
907                    (char*) indent, OP_NAMES[op]);
908                break;
909        }
910    }
911
912    DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
913    return needsInvalidate;
914}
915
916///////////////////////////////////////////////////////////////////////////////
917// Base structure
918///////////////////////////////////////////////////////////////////////////////
919
920DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), mHasDrawOps(false) {
921}
922
923DisplayListRenderer::~DisplayListRenderer() {
924    reset();
925}
926
927void DisplayListRenderer::reset() {
928    mWriter.reset();
929
930    Caches& caches = Caches::getInstance();
931    for (size_t i = 0; i < mBitmapResources.size(); i++) {
932        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
933    }
934    mBitmapResources.clear();
935
936    for (size_t i = 0; i < mFilterResources.size(); i++) {
937        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
938    }
939    mFilterResources.clear();
940
941    for (size_t i = 0; i < mShaders.size(); i++) {
942        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
943    }
944    mShaders.clear();
945    mShaderMap.clear();
946
947    mPaints.clear();
948    mPaintMap.clear();
949
950    mPaths.clear();
951    mPathMap.clear();
952
953    mMatrices.clear();
954
955    mHasDrawOps = false;
956}
957
958///////////////////////////////////////////////////////////////////////////////
959// Operations
960///////////////////////////////////////////////////////////////////////////////
961
962DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
963    if (!displayList) {
964        displayList = new DisplayList(*this);
965    } else {
966        displayList->initFromDisplayListRenderer(*this, true);
967    }
968    displayList->setRenderable(mHasDrawOps);
969    return displayList;
970}
971
972void DisplayListRenderer::setViewport(int width, int height) {
973    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
974
975    mWidth = width;
976    mHeight = height;
977}
978
979void DisplayListRenderer::prepareDirty(float left, float top,
980        float right, float bottom, bool opaque) {
981    mSnapshot = new Snapshot(mFirstSnapshot,
982            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
983    mSaveCount = 1;
984    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
985    mRestoreSaveCount = -1;
986}
987
988void DisplayListRenderer::finish() {
989    insertRestoreToCount();
990    OpenGLRenderer::finish();
991}
992
993void DisplayListRenderer::interrupt() {
994}
995
996void DisplayListRenderer::resume() {
997}
998
999bool DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
1000    // Ignore dirty during recording, it matters only when we replay
1001    addOp(DisplayList::DrawGLFunction);
1002    addInt((int) functor);
1003    return false; // No invalidate needed at record-time
1004}
1005
1006int DisplayListRenderer::save(int flags) {
1007    addOp(DisplayList::Save);
1008    addInt(flags);
1009    return OpenGLRenderer::save(flags);
1010}
1011
1012void DisplayListRenderer::restore() {
1013    if (mRestoreSaveCount < 0) {
1014        addOp(DisplayList::Restore);
1015    } else {
1016        mRestoreSaveCount--;
1017    }
1018    OpenGLRenderer::restore();
1019}
1020
1021void DisplayListRenderer::restoreToCount(int saveCount) {
1022    mRestoreSaveCount = saveCount;
1023    OpenGLRenderer::restoreToCount(saveCount);
1024}
1025
1026int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1027        SkPaint* p, int flags) {
1028    addOp(DisplayList::SaveLayer);
1029    addBounds(left, top, right, bottom);
1030    addPaint(p);
1031    addInt(flags);
1032    return OpenGLRenderer::save(flags);
1033}
1034
1035int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1036        int alpha, int flags) {
1037    addOp(DisplayList::SaveLayerAlpha);
1038    addBounds(left, top, right, bottom);
1039    addInt(alpha);
1040    addInt(flags);
1041    return OpenGLRenderer::save(flags);
1042}
1043
1044void DisplayListRenderer::translate(float dx, float dy) {
1045    addOp(DisplayList::Translate);
1046    addPoint(dx, dy);
1047    OpenGLRenderer::translate(dx, dy);
1048}
1049
1050void DisplayListRenderer::rotate(float degrees) {
1051    addOp(DisplayList::Rotate);
1052    addFloat(degrees);
1053    OpenGLRenderer::rotate(degrees);
1054}
1055
1056void DisplayListRenderer::scale(float sx, float sy) {
1057    addOp(DisplayList::Scale);
1058    addPoint(sx, sy);
1059    OpenGLRenderer::scale(sx, sy);
1060}
1061
1062void DisplayListRenderer::skew(float sx, float sy) {
1063    addOp(DisplayList::Skew);
1064    addPoint(sx, sy);
1065    OpenGLRenderer::skew(sx, sy);
1066}
1067
1068void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1069    addOp(DisplayList::SetMatrix);
1070    addMatrix(matrix);
1071    OpenGLRenderer::setMatrix(matrix);
1072}
1073
1074void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1075    addOp(DisplayList::ConcatMatrix);
1076    addMatrix(matrix);
1077    OpenGLRenderer::concatMatrix(matrix);
1078}
1079
1080bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1081        SkRegion::Op op) {
1082    addOp(DisplayList::ClipRect);
1083    addBounds(left, top, right, bottom);
1084    addInt(op);
1085    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1086}
1087
1088bool DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1089        uint32_t width, uint32_t height, Rect& dirty, uint32_t level) {
1090    // dirty is an out parameter and should not be recorded,
1091    // it matters only when replaying the display list
1092    addOp(DisplayList::DrawDisplayList);
1093    addDisplayList(displayList);
1094    addSize(width, height);
1095    return false;
1096}
1097
1098void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1099    addOp(DisplayList::DrawLayer);
1100    addInt((int) layer);
1101    addPoint(x, y);
1102    addPaint(paint);
1103}
1104
1105void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
1106        SkPaint* paint) {
1107    addOp(DisplayList::DrawBitmap);
1108    addBitmap(bitmap);
1109    addPoint(left, top);
1110    addPaint(paint);
1111}
1112
1113void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
1114        SkPaint* paint) {
1115    addOp(DisplayList::DrawBitmapMatrix);
1116    addBitmap(bitmap);
1117    addMatrix(matrix);
1118    addPaint(paint);
1119}
1120
1121void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1122        float srcRight, float srcBottom, float dstLeft, float dstTop,
1123        float dstRight, float dstBottom, SkPaint* paint) {
1124    addOp(DisplayList::DrawBitmapRect);
1125    addBitmap(bitmap);
1126    addBounds(srcLeft, srcTop, srcRight, srcBottom);
1127    addBounds(dstLeft, dstTop, dstRight, dstBottom);
1128    addPaint(paint);
1129}
1130
1131void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1132        float* vertices, int* colors, SkPaint* paint) {
1133    addOp(DisplayList::DrawBitmapMesh);
1134    addBitmap(bitmap);
1135    addInt(meshWidth);
1136    addInt(meshHeight);
1137    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1138    if (colors) {
1139        addInt(1);
1140        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1141    } else {
1142        addInt(0);
1143    }
1144    addPaint(paint);
1145}
1146
1147void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
1148        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
1149        float left, float top, float right, float bottom, SkPaint* paint) {
1150    addOp(DisplayList::DrawPatch);
1151    addBitmap(bitmap);
1152    addInts(xDivs, width);
1153    addInts(yDivs, height);
1154    addUInts(colors, numColors);
1155    addBounds(left, top, right, bottom);
1156    addPaint(paint);
1157}
1158
1159void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1160    addOp(DisplayList::DrawColor);
1161    addInt(color);
1162    addInt(mode);
1163}
1164
1165void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1166        SkPaint* paint) {
1167    addOp(DisplayList::DrawRect);
1168    addBounds(left, top, right, bottom);
1169    addPaint(paint);
1170}
1171
1172void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1173            float rx, float ry, SkPaint* paint) {
1174    addOp(DisplayList::DrawRoundRect);
1175    addBounds(left, top, right, bottom);
1176    addPoint(rx, ry);
1177    addPaint(paint);
1178}
1179
1180void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1181    addOp(DisplayList::DrawCircle);
1182    addPoint(x, y);
1183    addFloat(radius);
1184    addPaint(paint);
1185}
1186
1187void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1188        SkPaint* paint) {
1189    addOp(DisplayList::DrawOval);
1190    addBounds(left, top, right, bottom);
1191    addPaint(paint);
1192}
1193
1194void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1195        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1196    addOp(DisplayList::DrawArc);
1197    addBounds(left, top, right, bottom);
1198    addPoint(startAngle, sweepAngle);
1199    addInt(useCenter ? 1 : 0);
1200    addPaint(paint);
1201}
1202
1203void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1204    addOp(DisplayList::DrawPath);
1205    addPath(path);
1206    addPaint(paint);
1207}
1208
1209void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1210    addOp(DisplayList::DrawLines);
1211    addFloats(points, count);
1212    addPaint(paint);
1213}
1214
1215void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1216    addOp(DisplayList::DrawPoints);
1217    addFloats(points, count);
1218    addPaint(paint);
1219}
1220
1221void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
1222        float x, float y, SkPaint* paint, float length) {
1223    if (count <= 0) return;
1224    addOp(DisplayList::DrawText);
1225    addText(text, bytesCount);
1226    addInt(count);
1227    addPoint(x, y);
1228    // TODO: We should probably make a copy of the paint instead of modifying
1229    //       it; modifying the paint will change its generationID the first
1230    //       time, which might impact caches. More investigation needed to
1231    //       see if it matters.
1232    //       If we make a copy, then drawTextDecorations() should *not* make
1233    //       its own copy as it does right now.
1234    // Beware: this needs Glyph encoding (already done on the Paint constructor)
1235    paint->setAntiAlias(true);
1236    addPaint(paint);
1237    addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length);
1238}
1239
1240void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
1241        const float* positions, SkPaint* paint) {
1242    if (count <= 0) return;
1243    addOp(DisplayList::DrawPosText);
1244    addText(text, bytesCount);
1245    addInt(count);
1246    addFloats(positions, count * 2);
1247    paint->setAntiAlias(true);
1248    addPaint(paint);
1249}
1250
1251void DisplayListRenderer::resetShader() {
1252    addOp(DisplayList::ResetShader);
1253}
1254
1255void DisplayListRenderer::setupShader(SkiaShader* shader) {
1256    addOp(DisplayList::SetupShader);
1257    addShader(shader);
1258}
1259
1260void DisplayListRenderer::resetColorFilter() {
1261    addOp(DisplayList::ResetColorFilter);
1262}
1263
1264void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1265    addOp(DisplayList::SetupColorFilter);
1266    addColorFilter(filter);
1267}
1268
1269void DisplayListRenderer::resetShadow() {
1270    addOp(DisplayList::ResetShadow);
1271}
1272
1273void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1274    addOp(DisplayList::SetupShadow);
1275    addFloat(radius);
1276    addPoint(dx, dy);
1277    addInt(color);
1278}
1279
1280}; // namespace uirenderer
1281}; // namespace android
1282