DisplayListRenderer.cpp revision 82d41a515368236e56454bd84023bebd6306f6b7
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "OpenGLRenderer"
18
19#include "DisplayListRenderer.h"
20
21namespace android {
22namespace uirenderer {
23
24///////////////////////////////////////////////////////////////////////////////
25// Defines
26///////////////////////////////////////////////////////////////////////////////
27
28#define PATH_HEAP_SIZE 64
29
30///////////////////////////////////////////////////////////////////////////////
31// Helpers
32///////////////////////////////////////////////////////////////////////////////
33
34PathHeap::PathHeap(): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
35}
36
37PathHeap::PathHeap(SkFlattenableReadBuffer& buffer): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
38    int count = buffer.readS32();
39
40    mPaths.setCount(count);
41    SkPath** ptr = mPaths.begin();
42    SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath));
43
44    for (int i = 0; i < count; i++) {
45        new (p) SkPath;
46        p->unflatten(buffer);
47        *ptr++ = p;
48        p++;
49    }
50}
51
52PathHeap::~PathHeap() {
53    SkPath** iter = mPaths.begin();
54    SkPath** stop = mPaths.end();
55    while (iter < stop) {
56        (*iter)->~SkPath();
57        iter++;
58    }
59}
60
61int PathHeap::append(const SkPath& path) {
62    SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath));
63    new (p) SkPath(path);
64    *mPaths.append() = p;
65    return mPaths.count();
66}
67
68void PathHeap::flatten(SkFlattenableWriteBuffer& buffer) const {
69    int count = mPaths.count();
70
71    buffer.write32(count);
72    SkPath** iter = mPaths.begin();
73    SkPath** stop = mPaths.end();
74    while (iter < stop) {
75        (*iter)->flatten(buffer);
76        iter++;
77    }
78}
79
80///////////////////////////////////////////////////////////////////////////////
81// Display list
82///////////////////////////////////////////////////////////////////////////////
83
84const char* DisplayList::OP_NAMES[] = {
85    "AcquireContext",
86    "ReleaseContext",
87    "Save",
88    "Restore",
89    "RestoreToCount",
90    "SaveLayer",
91    "SaveLayerAlpha",
92    "Translate",
93    "Rotate",
94    "Scale",
95    "Skew",
96    "SetMatrix",
97    "ConcatMatrix",
98    "ClipRect",
99    "DrawDisplayList",
100    "DrawLayer",
101    "DrawBitmap",
102    "DrawBitmapMatrix",
103    "DrawBitmapRect",
104    "DrawBitmapMesh",
105    "DrawPatch",
106    "DrawColor",
107    "DrawRect",
108    "DrawRoundRect",
109    "DrawCircle",
110    "DrawOval",
111    "DrawArc",
112    "DrawPath",
113    "DrawLines",
114    "DrawText",
115    "ResetShader",
116    "SetupShader",
117    "ResetColorFilter",
118    "SetupColorFilter",
119    "ResetShadow",
120    "SetupShadow",
121    "DrawGLFunction"
122};
123
124DisplayList::DisplayList(const DisplayListRenderer& recorder) {
125    initFromDisplayListRenderer(recorder);
126}
127
128DisplayList::~DisplayList() {
129    sk_free((void*) mReader.base());
130
131    Caches& caches = Caches::getInstance();
132
133    for (size_t i = 0; i < mBitmapResources.size(); i++) {
134        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
135    }
136    mBitmapResources.clear();
137
138    for (size_t i = 0; i < mShaders.size(); i++) {
139        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
140    }
141    mShaders.clear();
142
143    for (size_t i = 0; i < mPaints.size(); i++) {
144        delete mPaints.itemAt(i);
145    }
146    mPaints.clear();
147
148    for (size_t i = 0; i < mMatrices.size(); i++) {
149        delete mMatrices.itemAt(i);
150    }
151    mMatrices.clear();
152
153    if (mPathHeap) {
154        for (int i = 0; i < mPathHeap->count(); i++) {
155            caches.pathCache.removeDeferred(&(*mPathHeap)[i]);
156        }
157        mPathHeap->safeUnref();
158    }
159}
160
161void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) {
162    const SkWriter32& writer = recorder.writeStream();
163    init();
164
165    if (writer.size() == 0) {
166        return;
167    }
168
169    size_t size = writer.size();
170    void* buffer = sk_malloc_throw(size);
171    writer.flatten(buffer);
172    mReader.setMemory(buffer, size);
173
174    mRCPlayback.reset(&recorder.mRCRecorder);
175    mRCPlayback.setupBuffer(mReader);
176
177    mTFPlayback.reset(&recorder.mTFRecorder);
178    mTFPlayback.setupBuffer(mReader);
179
180    Caches& caches = Caches::getInstance();
181
182    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
183    for (size_t i = 0; i < bitmapResources.size(); i++) {
184        SkBitmap* resource = bitmapResources.itemAt(i);
185        mBitmapResources.add(resource);
186        caches.resourceCache.incrementRefcount(resource);
187    }
188
189    const Vector<SkiaShader*> &shaders = recorder.getShaders();
190    for (size_t i = 0; i < shaders.size(); i++) {
191        SkiaShader* shader = shaders.itemAt(i);
192        mShaders.add(shader);
193        caches.resourceCache.incrementRefcount(shader);
194    }
195
196    const Vector<SkPaint*> &paints = recorder.getPaints();
197    for (size_t i = 0; i < paints.size(); i++) {
198        mPaints.add(paints.itemAt(i));
199    }
200
201    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
202    for (size_t i = 0; i < matrices.size(); i++) {
203        mMatrices.add(matrices.itemAt(i));
204    }
205
206    mPathHeap = recorder.mPathHeap;
207    if (mPathHeap) {
208        mPathHeap->safeRef();
209    }
210}
211
212void DisplayList::init() {
213    mPathHeap = NULL;
214}
215
216bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
217    bool needsInvalidate = false;
218    TextContainer text;
219    mReader.rewind();
220
221#if DEBUG_DISPLAY_LIST
222    uint32_t count = (level + 1) * 2;
223    char indent[count + 1];
224    for (uint32_t i = 0; i < count; i++) {
225        indent[i] = ' ';
226    }
227    indent[count] = '\0';
228    DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this);
229#endif
230
231    int saveCount = renderer.getSaveCount() - 1;
232    while (!mReader.eof()) {
233        int op = mReader.readInt();
234
235        switch (op) {
236            case DrawGLFunction: {
237                Functor *functor = (Functor *) getInt();
238                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
239                needsInvalidate |= renderer.callDrawGLFunction(functor);
240            }
241            break;
242            case AcquireContext: {
243                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
244                renderer.acquireContext();
245            }
246            break;
247            case ReleaseContext: {
248                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
249                renderer.releaseContext();
250            }
251            break;
252            case Save: {
253                int rendererNum = getInt();
254                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
255                renderer.save(rendererNum);
256            }
257            break;
258            case Restore: {
259                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
260                renderer.restore();
261            }
262            break;
263            case RestoreToCount: {
264                int restoreCount = saveCount + getInt();
265                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
266                renderer.restoreToCount(restoreCount);
267            }
268            break;
269            case SaveLayer: {
270                float f1 = getFloat();
271                float f2 = getFloat();
272                float f3 = getFloat();
273                float f4 = getFloat();
274                SkPaint* paint = getPaint();
275                int flags = getInt();
276                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
277                    OP_NAMES[op], f1, f2, f3, f4, paint, flags);
278                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
279            }
280            break;
281            case SaveLayerAlpha: {
282                float f1 = getFloat();
283                float f2 = getFloat();
284                float f3 = getFloat();
285                float f4 = getFloat();
286                int alpha = getInt();
287                int flags = getInt();
288                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
289                    OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
290                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
291            }
292            break;
293            case Translate: {
294                float f1 = getFloat();
295                float f2 = getFloat();
296                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
297                renderer.translate(f1, f2);
298            }
299            break;
300            case Rotate: {
301                float rotation = getFloat();
302                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
303                renderer.rotate(rotation);
304            }
305            break;
306            case Scale: {
307                float sx = getFloat();
308                float sy = getFloat();
309                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
310                renderer.scale(sx, sy);
311            }
312            break;
313            case Skew: {
314                float sx = getFloat();
315                float sy = getFloat();
316                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
317                renderer.skew(sx, sy);
318            }
319            break;
320            case SetMatrix: {
321                SkMatrix* matrix = getMatrix();
322                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
323                renderer.setMatrix(matrix);
324            }
325            break;
326            case ConcatMatrix: {
327                SkMatrix* matrix = getMatrix();
328                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
329                renderer.concatMatrix(matrix);
330            }
331            break;
332            case ClipRect: {
333                float f1 = getFloat();
334                float f2 = getFloat();
335                float f3 = getFloat();
336                float f4 = getFloat();
337                int regionOp = getInt();
338                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
339                    f1, f2, f3, f4, regionOp);
340                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
341            }
342            break;
343            case DrawDisplayList: {
344                DisplayList* displayList = getDisplayList();
345                DISPLAY_LIST_LOGD("%s%s %p, %d", (char*) indent, OP_NAMES[op],
346                    displayList, level + 1);
347                needsInvalidate |= renderer.drawDisplayList(displayList, level + 1);
348            }
349            break;
350            case DrawLayer: {
351                Layer* layer = (Layer*) getInt();
352                float x = getFloat();
353                float y = getFloat();
354                SkPaint* paint = getPaint();
355                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
356                    layer, x, y, paint);
357                renderer.drawLayer(layer, x, y, paint);
358            }
359            break;
360            case DrawBitmap: {
361                SkBitmap* bitmap = getBitmap();
362                float x = getFloat();
363                float y = getFloat();
364                SkPaint* paint = getPaint();
365                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
366                    bitmap, x, y, paint);
367                renderer.drawBitmap(bitmap, x, y, paint);
368            }
369            break;
370            case DrawBitmapMatrix: {
371                SkBitmap* bitmap = getBitmap();
372                SkMatrix* matrix = getMatrix();
373                SkPaint* paint = getPaint();
374                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
375                    bitmap, matrix, paint);
376                renderer.drawBitmap(bitmap, matrix, paint);
377            }
378            break;
379            case DrawBitmapRect: {
380                SkBitmap* bitmap = getBitmap();
381                float f1 = getFloat();
382                float f2 = getFloat();
383                float f3 = getFloat();
384                float f4 = getFloat();
385                float f5 = getFloat();
386                float f6 = getFloat();
387                float f7 = getFloat();
388                float f8 = getFloat();
389                SkPaint* paint = getPaint();
390                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
391                    (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
392                renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
393            }
394            break;
395            case DrawBitmapMesh: {
396                int verticesCount = 0;
397                uint32_t colorsCount = 0;
398
399                SkBitmap* bitmap = getBitmap();
400                uint32_t meshWidth = getInt();
401                uint32_t meshHeight = getInt();
402                float* vertices = getFloats(verticesCount);
403                bool hasColors = getInt();
404                int* colors = hasColors ? getInts(colorsCount) : NULL;
405
406                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
407                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
408            }
409            break;
410            case DrawPatch: {
411                int32_t* xDivs = NULL;
412                int32_t* yDivs = NULL;
413                uint32_t* colors = NULL;
414                uint32_t xDivsCount = 0;
415                uint32_t yDivsCount = 0;
416                int8_t numColors = 0;
417
418                SkBitmap* bitmap = getBitmap();
419
420                xDivs = getInts(xDivsCount);
421                yDivs = getInts(yDivsCount);
422                colors = getUInts(numColors);
423
424                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
425                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
426                        numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
427            }
428            break;
429            case DrawColor: {
430                int color = getInt();
431                int xferMode = getInt();
432                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
433                renderer.drawColor(color, (SkXfermode::Mode) xferMode);
434            }
435            break;
436            case DrawRect: {
437                float f1 = getFloat();
438                float f2 = getFloat();
439                float f3 = getFloat();
440                float f4 = getFloat();
441                SkPaint* paint = getPaint();
442                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
443                    f1, f2, f3, f4, paint);
444                renderer.drawRect(f1, f2, f3, f4, paint);
445            }
446            break;
447            case DrawRoundRect: {
448                float f1 = getFloat();
449                float f2 = getFloat();
450                float f3 = getFloat();
451                float f4 = getFloat();
452                float f5 = getFloat();
453                float f6 = getFloat();
454                SkPaint* paint = getPaint();
455                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
456                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
457                renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
458            }
459            break;
460            case DrawCircle: {
461                float f1 = getFloat();
462                float f2 = getFloat();
463                float f3 = getFloat();
464                SkPaint* paint = getPaint();
465                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
466                    (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
467                renderer.drawCircle(f1, f2, f3, paint);
468            }
469            break;
470            case DrawOval: {
471                float f1 = getFloat();
472                float f2 = getFloat();
473                float f3 = getFloat();
474                float f4 = getFloat();
475                SkPaint* paint = getPaint();
476                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
477                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
478                renderer.drawOval(f1, f2, f3, f4, paint);
479            }
480            break;
481            case DrawArc: {
482                float f1 = getFloat();
483                float f2 = getFloat();
484                float f3 = getFloat();
485                float f4 = getFloat();
486                float f5 = getFloat();
487                float f6 = getFloat();
488                int i1 = getInt();
489                SkPaint* paint = getPaint();
490                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
491                    (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
492                renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
493            }
494            break;
495            case DrawPath: {
496                SkPath* path = getPath();
497                SkPaint* paint = getPaint();
498                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
499                renderer.drawPath(path, paint);
500            }
501            break;
502            case DrawLines: {
503                int count = 0;
504                float* points = getFloats(count);
505                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
506                renderer.drawLines(points, count, getPaint());
507            }
508            break;
509            case DrawText: {
510                getText(&text);
511                int count = getInt();
512                float x = getFloat();
513                float y = getFloat();
514                SkPaint* paint = getPaint();
515                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
516                    text.text(), text.length(), count, x, y, paint);
517                renderer.drawText(text.text(), text.length(), count, x, y, paint);
518            }
519            break;
520            case ResetShader: {
521                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
522                renderer.resetShader();
523            }
524            break;
525            case SetupShader: {
526                SkiaShader* shader = getShader();
527                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
528                renderer.setupShader(shader);
529            }
530            break;
531            case ResetColorFilter: {
532                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
533                renderer.resetColorFilter();
534            }
535            break;
536            case SetupColorFilter: {
537                SkiaColorFilter *colorFilter = getColorFilter();
538                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
539                renderer.setupColorFilter(colorFilter);
540            }
541            break;
542            case ResetShadow: {
543                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
544                renderer.resetShadow();
545            }
546            break;
547            case SetupShadow: {
548                float radius = getFloat();
549                float dx = getFloat();
550                float dy = getFloat();
551                int color = getInt();
552                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
553                    radius, dx, dy, color);
554                renderer.setupShadow(radius, dx, dy, color);
555            }
556            break;
557            default:
558                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
559                    (char*) indent, OP_NAMES[op]);
560                break;
561        }
562    }
563
564    DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
565    return needsInvalidate;
566}
567
568///////////////////////////////////////////////////////////////////////////////
569// Base structure
570///////////////////////////////////////////////////////////////////////////////
571
572DisplayListRenderer::DisplayListRenderer():
573        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
574    mPathHeap = NULL;
575    mDisplayList = NULL;
576}
577
578DisplayListRenderer::~DisplayListRenderer() {
579    reset();
580}
581
582void DisplayListRenderer::reset() {
583    if (mPathHeap) {
584        mPathHeap->unref();
585        mPathHeap = NULL;
586    }
587
588    mWriter.reset();
589    mHeap.reset();
590
591    mRCRecorder.reset();
592    mTFRecorder.reset();
593
594    Caches& caches = Caches::getInstance();
595    for (size_t i = 0; i < mBitmapResources.size(); i++) {
596        SkBitmap* resource = mBitmapResources.itemAt(i);
597        caches.resourceCache.decrementRefcount(resource);
598    }
599    mBitmapResources.clear();
600
601    for (size_t i = 0; i < mShaders.size(); i++) {
602       caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
603    }
604    mShaders.clear();
605    mShaderMap.clear();
606
607    mPaints.clear();
608    mPaintMap.clear();
609    mMatrices.clear();
610}
611
612///////////////////////////////////////////////////////////////////////////////
613// Operations
614///////////////////////////////////////////////////////////////////////////////
615
616DisplayList* DisplayListRenderer::getDisplayList() {
617    if (mDisplayList == NULL) {
618        mDisplayList = new DisplayList(*this);
619    } else {
620        mDisplayList->initFromDisplayListRenderer(*this);
621    }
622    return mDisplayList;
623}
624
625void DisplayListRenderer::setViewport(int width, int height) {
626    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
627
628    mWidth = width;
629    mHeight = height;
630}
631
632void DisplayListRenderer::prepareDirty(float left, float top,
633        float right, float bottom, bool opaque) {
634    mSnapshot = new Snapshot(mFirstSnapshot,
635            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
636    mSaveCount = 1;
637    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
638    mRestoreSaveCount = -1;
639}
640
641void DisplayListRenderer::finish() {
642    insertRestoreToCount();
643    OpenGLRenderer::finish();
644}
645
646void DisplayListRenderer::interrupt() {
647
648}
649void DisplayListRenderer::resume() {
650
651}
652void DisplayListRenderer::acquireContext() {
653    // TODO: probably noop instead of calling super
654    addOp(DisplayList::AcquireContext);
655    OpenGLRenderer::acquireContext();
656}
657
658bool DisplayListRenderer::callDrawGLFunction(Functor *functor) {
659    addOp(DisplayList::DrawGLFunction);
660    addInt((int) functor);
661    return false; // No invalidate needed at record-time
662}
663
664void DisplayListRenderer::releaseContext() {
665    // TODO: probably noop instead of calling super
666    addOp(DisplayList::ReleaseContext);
667    OpenGLRenderer::releaseContext();
668}
669
670int DisplayListRenderer::save(int flags) {
671    addOp(DisplayList::Save);
672    addInt(flags);
673    return OpenGLRenderer::save(flags);
674}
675
676void DisplayListRenderer::restore() {
677    addOp(DisplayList::Restore);
678    OpenGLRenderer::restore();
679}
680
681void DisplayListRenderer::restoreToCount(int saveCount) {
682    mRestoreSaveCount = saveCount;
683    OpenGLRenderer::restoreToCount(saveCount);
684}
685
686int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
687        SkPaint* p, int flags) {
688    addOp(DisplayList::SaveLayer);
689    addBounds(left, top, right, bottom);
690    addPaint(p);
691    addInt(flags);
692    return OpenGLRenderer::save(flags);
693}
694
695int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
696        int alpha, int flags) {
697    addOp(DisplayList::SaveLayerAlpha);
698    addBounds(left, top, right, bottom);
699    addInt(alpha);
700    addInt(flags);
701    return OpenGLRenderer::save(flags);
702}
703
704void DisplayListRenderer::translate(float dx, float dy) {
705    addOp(DisplayList::Translate);
706    addPoint(dx, dy);
707    OpenGLRenderer::translate(dx, dy);
708}
709
710void DisplayListRenderer::rotate(float degrees) {
711    addOp(DisplayList::Rotate);
712    addFloat(degrees);
713    OpenGLRenderer::rotate(degrees);
714}
715
716void DisplayListRenderer::scale(float sx, float sy) {
717    addOp(DisplayList::Scale);
718    addPoint(sx, sy);
719    OpenGLRenderer::scale(sx, sy);
720}
721
722void DisplayListRenderer::skew(float sx, float sy) {
723    addOp(DisplayList::Skew);
724    addPoint(sx, sy);
725    OpenGLRenderer::skew(sx, sy);
726}
727
728void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
729    addOp(DisplayList::SetMatrix);
730    addMatrix(matrix);
731    OpenGLRenderer::setMatrix(matrix);
732}
733
734void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
735    addOp(DisplayList::ConcatMatrix);
736    addMatrix(matrix);
737    OpenGLRenderer::concatMatrix(matrix);
738}
739
740bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
741        SkRegion::Op op) {
742    addOp(DisplayList::ClipRect);
743    addBounds(left, top, right, bottom);
744    addInt(op);
745    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
746}
747
748bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
749    addOp(DisplayList::DrawDisplayList);
750    addDisplayList(displayList);
751    return false;
752}
753
754void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
755    addOp(DisplayList::DrawLayer);
756    addInt((int) layer);
757    addPoint(x, y);
758    addPaint(paint);
759}
760
761void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
762        SkPaint* paint) {
763    addOp(DisplayList::DrawBitmap);
764    addBitmap(bitmap);
765    addPoint(left, top);
766    addPaint(paint);
767}
768
769void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
770        SkPaint* paint) {
771    addOp(DisplayList::DrawBitmapMatrix);
772    addBitmap(bitmap);
773    addMatrix(matrix);
774    addPaint(paint);
775}
776
777void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
778        float srcRight, float srcBottom, float dstLeft, float dstTop,
779        float dstRight, float dstBottom, SkPaint* paint) {
780    addOp(DisplayList::DrawBitmapRect);
781    addBitmap(bitmap);
782    addBounds(srcLeft, srcTop, srcRight, srcBottom);
783    addBounds(dstLeft, dstTop, dstRight, dstBottom);
784    addPaint(paint);
785}
786
787void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
788        float* vertices, int* colors, SkPaint* paint) {
789    addOp(DisplayList::DrawBitmapMesh);
790    addBitmap(bitmap);
791    addInt(meshWidth);
792    addInt(meshHeight);
793    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
794    if (colors) {
795        addInt(1);
796        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
797    } else {
798        addInt(0);
799    }
800    addPaint(paint);
801}
802
803void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
804        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
805        float left, float top, float right, float bottom, SkPaint* paint) {
806    addOp(DisplayList::DrawPatch);
807    addBitmap(bitmap);
808    addInts(xDivs, width);
809    addInts(yDivs, height);
810    addUInts(colors, numColors);
811    addBounds(left, top, right, bottom);
812    addPaint(paint);
813}
814
815void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
816    addOp(DisplayList::DrawColor);
817    addInt(color);
818    addInt(mode);
819}
820
821void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
822        SkPaint* paint) {
823    addOp(DisplayList::DrawRect);
824    addBounds(left, top, right, bottom);
825    addPaint(paint);
826}
827
828void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
829            float rx, float ry, SkPaint* paint) {
830    addOp(DisplayList::DrawRoundRect);
831    addBounds(left, top, right, bottom);
832    addPoint(rx, ry);
833    addPaint(paint);
834}
835
836void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
837    addOp(DisplayList::DrawCircle);
838    addPoint(x, y);
839    addFloat(radius);
840    addPaint(paint);
841}
842
843void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
844        SkPaint* paint) {
845    addOp(DisplayList::DrawOval);
846    addBounds(left, top, right, bottom);
847    addPaint(paint);
848}
849
850void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
851        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
852    addOp(DisplayList::DrawArc);
853    addBounds(left, top, right, bottom);
854    addPoint(startAngle, sweepAngle);
855    addInt(useCenter ? 1 : 0);
856    addPaint(paint);
857}
858
859void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
860    addOp(DisplayList::DrawPath);
861    addPath(path);
862    addPaint(paint);
863}
864
865void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
866    addOp(DisplayList::DrawLines);
867    addFloats(points, count);
868    addPaint(paint);
869}
870
871void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
872        float x, float y, SkPaint* paint) {
873    addOp(DisplayList::DrawText);
874    addText(text, bytesCount);
875    addInt(count);
876    addPoint(x, y);
877    addPaint(paint);
878}
879
880void DisplayListRenderer::resetShader() {
881    addOp(DisplayList::ResetShader);
882}
883
884void DisplayListRenderer::setupShader(SkiaShader* shader) {
885    addOp(DisplayList::SetupShader);
886    addShader(shader);
887}
888
889void DisplayListRenderer::resetColorFilter() {
890    addOp(DisplayList::ResetColorFilter);
891}
892
893void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
894    addOp(DisplayList::SetupColorFilter);
895    addColorFilter(filter);
896}
897
898void DisplayListRenderer::resetShadow() {
899    addOp(DisplayList::ResetShadow);
900}
901
902void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
903    addOp(DisplayList::SetupShadow);
904    addFloat(radius);
905    addPoint(dx, dy);
906    addInt(color);
907}
908
909}; // namespace uirenderer
910}; // namespace android
911