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