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