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