DisplayListRenderer.cpp revision c1cd9ba335b293f11e1082447ef08e474710a05f
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    "DrawPath",
112    "DrawLines",
113    "DrawText",
114    "ResetShader",
115    "SetupShader",
116    "ResetColorFilter",
117    "SetupColorFilter",
118    "ResetShadow",
119    "SetupShadow"
120};
121
122DisplayList::DisplayList(const DisplayListRenderer& recorder) {
123    initFromDisplayListRenderer(recorder);
124}
125
126DisplayList::~DisplayList() {
127    sk_free((void*) mReader.base());
128
129    Caches& caches = Caches::getInstance();
130
131    for (size_t i = 0; i < mBitmapResources.size(); i++) {
132        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
133    }
134    mBitmapResources.clear();
135
136    for (size_t i = 0; i < mShaders.size(); i++) {
137        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
138    }
139    mShaders.clear();
140
141    for (size_t i = 0; i < mPaints.size(); i++) {
142        delete mPaints.itemAt(i);
143    }
144    mPaints.clear();
145
146    for (size_t i = 0; i < mMatrices.size(); i++) {
147        delete mMatrices.itemAt(i);
148    }
149    mMatrices.clear();
150
151    if (mPathHeap) {
152        for (int i = 0; i < mPathHeap->count(); i++) {
153            caches.pathCache.removeDeferred(&(*mPathHeap)[i]);
154        }
155        mPathHeap->safeUnref();
156    }
157}
158
159void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) {
160    const SkWriter32& writer = recorder.writeStream();
161    init();
162
163    if (writer.size() == 0) {
164        return;
165    }
166
167    size_t size = writer.size();
168    void* buffer = sk_malloc_throw(size);
169    writer.flatten(buffer);
170    mReader.setMemory(buffer, size);
171
172    mRCPlayback.reset(&recorder.mRCRecorder);
173    mRCPlayback.setupBuffer(mReader);
174
175    mTFPlayback.reset(&recorder.mTFRecorder);
176    mTFPlayback.setupBuffer(mReader);
177
178    Caches& caches = Caches::getInstance();
179
180    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
181    for (size_t i = 0; i < bitmapResources.size(); i++) {
182        SkBitmap* resource = bitmapResources.itemAt(i);
183        mBitmapResources.add(resource);
184        caches.resourceCache.incrementRefcount(resource);
185    }
186
187    const Vector<SkiaShader*> &shaders = recorder.getShaders();
188    for (size_t i = 0; i < shaders.size(); i++) {
189        SkiaShader* shader = shaders.itemAt(i);
190        mShaders.add(shader);
191        caches.resourceCache.incrementRefcount(shader);
192    }
193
194    const Vector<SkPaint*> &paints = recorder.getPaints();
195    for (size_t i = 0; i < paints.size(); i++) {
196        mPaints.add(paints.itemAt(i));
197    }
198
199    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
200    for (size_t i = 0; i < matrices.size(); i++) {
201        mMatrices.add(matrices.itemAt(i));
202    }
203
204    mPathHeap = recorder.mPathHeap;
205    if (mPathHeap) {
206        mPathHeap->safeRef();
207    }
208}
209
210void DisplayList::init() {
211    mPathHeap = NULL;
212}
213
214void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
215    TextContainer text;
216    mReader.rewind();
217
218#if DEBUG_DISPLAY_LIST
219    uint32_t count = (level + 1) * 2;
220    char indent[count + 1];
221    for (uint32_t i = 0; i < count; i++) {
222        indent[i] = ' ';
223    }
224    indent[count] = '\0';
225    DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this);
226#endif
227
228    int saveCount = renderer.getSaveCount() - 1;
229    while (!mReader.eof()) {
230        int op = mReader.readInt();
231        DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
232
233        switch (op) {
234            case AcquireContext: {
235                renderer.acquireContext();
236            }
237            break;
238            case ReleaseContext: {
239                renderer.releaseContext();
240            }
241            break;
242            case Save: {
243                renderer.save(getInt());
244            }
245            break;
246            case Restore: {
247                renderer.restore();
248            }
249            break;
250            case RestoreToCount: {
251                renderer.restoreToCount(saveCount + getInt());
252            }
253            break;
254            case SaveLayer: {
255                renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
256                        getPaint(), getInt());
257            }
258            break;
259            case SaveLayerAlpha: {
260                renderer.saveLayerAlpha(getFloat(), getFloat(), getFloat(), getFloat(),
261                        getInt(), getInt());
262            }
263            break;
264            case Translate: {
265                renderer.translate(getFloat(), getFloat());
266            }
267            break;
268            case Rotate: {
269                renderer.rotate(getFloat());
270            }
271            break;
272            case Scale: {
273                renderer.scale(getFloat(), getFloat());
274            }
275            break;
276            case Skew: {
277                renderer.skew(getFloat(), getFloat());
278            }
279            break;
280            case SetMatrix: {
281                renderer.setMatrix(getMatrix());
282            }
283            break;
284            case ConcatMatrix: {
285                renderer.concatMatrix(getMatrix());
286            }
287            break;
288            case ClipRect: {
289                renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
290                        (SkRegion::Op) getInt());
291            }
292            break;
293            case DrawDisplayList: {
294                renderer.drawDisplayList(getDisplayList(), level + 1);
295            }
296            break;
297            case DrawLayer: {
298                renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint());
299            }
300            break;
301            case DrawBitmap: {
302                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
303            }
304            break;
305            case DrawBitmapMatrix: {
306                renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
307            }
308            break;
309            case DrawBitmapRect: {
310                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
311                        getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
312            }
313            break;
314            case DrawBitmapMesh: {
315                int verticesCount = 0;
316                uint32_t colorsCount = 0;
317
318                SkBitmap* bitmap = getBitmap();
319                uint32_t meshWidth = getInt();
320                uint32_t meshHeight = getInt();
321                float* vertices = getFloats(verticesCount);
322                bool hasColors = getInt();
323                int* colors = hasColors ? getInts(colorsCount) : NULL;
324
325                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
326            }
327            case DrawPatch: {
328                int32_t* xDivs = NULL;
329                int32_t* yDivs = NULL;
330                uint32_t* colors = NULL;
331                uint32_t xDivsCount = 0;
332                uint32_t yDivsCount = 0;
333                int8_t numColors = 0;
334
335                SkBitmap* bitmap = getBitmap();
336
337                xDivs = getInts(xDivsCount);
338                yDivs = getInts(yDivsCount);
339                colors = getUInts(numColors);
340
341                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
342                        numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
343            }
344            break;
345            case DrawColor: {
346                renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
347            }
348            break;
349            case DrawRect: {
350                renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
351            }
352            break;
353            case DrawRoundRect: {
354                renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
355                        getFloat(), getFloat(), getPaint());
356            }
357            break;
358            case DrawCircle: {
359                renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
360            }
361            break;
362            case DrawOval: {
363                renderer.drawOval(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
364            }
365            break;
366            case DrawPath: {
367                renderer.drawPath(getPath(), getPaint());
368            }
369            break;
370            case DrawLines: {
371                int count = 0;
372                float* points = getFloats(count);
373                renderer.drawLines(points, count, getPaint());
374            }
375            break;
376            case DrawText: {
377                getText(&text);
378                renderer.drawText(text.text(), text.length(), getInt(),
379                        getFloat(), getFloat(), getPaint());
380            }
381            break;
382            case ResetShader: {
383                renderer.resetShader();
384            }
385            break;
386            case SetupShader: {
387                renderer.setupShader(getShader());
388            }
389            break;
390            case ResetColorFilter: {
391                renderer.resetColorFilter();
392            }
393            break;
394            case SetupColorFilter: {
395                renderer.setupColorFilter(getColorFilter());
396            }
397            break;
398            case ResetShadow: {
399                renderer.resetShadow();
400            }
401            break;
402            case SetupShadow: {
403                renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
404            }
405            break;
406        }
407    }
408
409    DISPLAY_LIST_LOGD("%sDone", (char*) indent + 2);
410}
411
412///////////////////////////////////////////////////////////////////////////////
413// Base structure
414///////////////////////////////////////////////////////////////////////////////
415
416DisplayListRenderer::DisplayListRenderer():
417        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
418    mPathHeap = NULL;
419    mDisplayList = NULL;
420}
421
422DisplayListRenderer::~DisplayListRenderer() {
423    reset();
424}
425
426void DisplayListRenderer::reset() {
427    if (mPathHeap) {
428        mPathHeap->unref();
429        mPathHeap = NULL;
430    }
431
432    mWriter.reset();
433    mHeap.reset();
434
435    mRCRecorder.reset();
436    mTFRecorder.reset();
437
438    Caches& caches = Caches::getInstance();
439    for (size_t i = 0; i < mBitmapResources.size(); i++) {
440        SkBitmap* resource = mBitmapResources.itemAt(i);
441        caches.resourceCache.decrementRefcount(resource);
442    }
443    mBitmapResources.clear();
444
445    for (size_t i = 0; i < mShaders.size(); i++) {
446       caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
447    }
448    mShaders.clear();
449    mShaderMap.clear();
450
451    mPaints.clear();
452    mPaintMap.clear();
453    mMatrices.clear();
454}
455
456///////////////////////////////////////////////////////////////////////////////
457// Operations
458///////////////////////////////////////////////////////////////////////////////
459
460DisplayList* DisplayListRenderer::getDisplayList() {
461    if (mDisplayList == NULL) {
462        mDisplayList = new DisplayList(*this);
463    } else {
464        mDisplayList->initFromDisplayListRenderer(*this);
465    }
466    return mDisplayList;
467}
468
469void DisplayListRenderer::setViewport(int width, int height) {
470    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
471
472    mWidth = width;
473    mHeight = height;
474}
475
476void DisplayListRenderer::prepare(bool opaque) {
477    mSnapshot = new Snapshot(mFirstSnapshot,
478            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
479    mSaveCount = 1;
480    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
481    mRestoreSaveCount = -1;
482}
483
484void DisplayListRenderer::finish() {
485    insertRestoreToCount();
486    OpenGLRenderer::finish();
487}
488
489void DisplayListRenderer::acquireContext() {
490    addOp(DisplayList::AcquireContext);
491    OpenGLRenderer::acquireContext();
492}
493
494void DisplayListRenderer::releaseContext() {
495    addOp(DisplayList::ReleaseContext);
496    OpenGLRenderer::releaseContext();
497}
498
499int DisplayListRenderer::save(int flags) {
500    addOp(DisplayList::Save);
501    addInt(flags);
502    return OpenGLRenderer::save(flags);
503}
504
505void DisplayListRenderer::restore() {
506    addOp(DisplayList::Restore);
507    OpenGLRenderer::restore();
508}
509
510void DisplayListRenderer::restoreToCount(int saveCount) {
511    mRestoreSaveCount = saveCount;
512    OpenGLRenderer::restoreToCount(saveCount);
513}
514
515int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
516        SkPaint* p, int flags) {
517    addOp(DisplayList::SaveLayer);
518    addBounds(left, top, right, bottom);
519    addPaint(p);
520    addInt(flags);
521    return OpenGLRenderer::save(flags);
522}
523
524int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
525        int alpha, int flags) {
526    addOp(DisplayList::SaveLayerAlpha);
527    addBounds(left, top, right, bottom);
528    addInt(alpha);
529    addInt(flags);
530    return OpenGLRenderer::save(flags);
531}
532
533void DisplayListRenderer::translate(float dx, float dy) {
534    addOp(DisplayList::Translate);
535    addPoint(dx, dy);
536    OpenGLRenderer::translate(dx, dy);
537}
538
539void DisplayListRenderer::rotate(float degrees) {
540    addOp(DisplayList::Rotate);
541    addFloat(degrees);
542    OpenGLRenderer::rotate(degrees);
543}
544
545void DisplayListRenderer::scale(float sx, float sy) {
546    addOp(DisplayList::Scale);
547    addPoint(sx, sy);
548    OpenGLRenderer::scale(sx, sy);
549}
550
551void DisplayListRenderer::skew(float sx, float sy) {
552    addOp(DisplayList::Skew);
553    addPoint(sx, sy);
554    OpenGLRenderer::skew(sx, sy);
555}
556
557void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
558    addOp(DisplayList::SetMatrix);
559    addMatrix(matrix);
560    OpenGLRenderer::setMatrix(matrix);
561}
562
563void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
564    addOp(DisplayList::ConcatMatrix);
565    addMatrix(matrix);
566    OpenGLRenderer::concatMatrix(matrix);
567}
568
569bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
570        SkRegion::Op op) {
571    addOp(DisplayList::ClipRect);
572    addBounds(left, top, right, bottom);
573    addInt(op);
574    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
575}
576
577void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
578    addOp(DisplayList::DrawDisplayList);
579    addDisplayList(displayList);
580}
581
582void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
583    addOp(DisplayList::DrawLayer);
584    addInt((int) layer);
585    addPoint(x, y);
586    addPaint(paint);
587}
588
589void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
590        SkPaint* paint) {
591    addOp(DisplayList::DrawBitmap);
592    addBitmap(bitmap);
593    addPoint(left, top);
594    addPaint(paint);
595}
596
597void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
598        SkPaint* paint) {
599    addOp(DisplayList::DrawBitmapMatrix);
600    addBitmap(bitmap);
601    addMatrix(matrix);
602    addPaint(paint);
603}
604
605void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
606        float srcRight, float srcBottom, float dstLeft, float dstTop,
607        float dstRight, float dstBottom, SkPaint* paint) {
608    addOp(DisplayList::DrawBitmapRect);
609    addBitmap(bitmap);
610    addBounds(srcLeft, srcTop, srcRight, srcBottom);
611    addBounds(dstLeft, dstTop, dstRight, dstBottom);
612    addPaint(paint);
613}
614
615void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
616        float* vertices, int* colors, SkPaint* paint) {
617    addOp(DisplayList::DrawBitmapMesh);
618    addBitmap(bitmap);
619    addInt(meshWidth);
620    addInt(meshHeight);
621    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
622    if (colors) {
623        addInt(1);
624        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
625    } else {
626        addInt(0);
627    }
628    addPaint(paint);
629}
630
631void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
632        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
633        float left, float top, float right, float bottom, SkPaint* paint) {
634    addOp(DisplayList::DrawPatch);
635    addBitmap(bitmap);
636    addInts(xDivs, width);
637    addInts(yDivs, height);
638    addUInts(colors, numColors);
639    addBounds(left, top, right, bottom);
640    addPaint(paint);
641}
642
643void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
644    addOp(DisplayList::DrawColor);
645    addInt(color);
646    addInt(mode);
647}
648
649void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
650        SkPaint* paint) {
651    addOp(DisplayList::DrawRect);
652    addBounds(left, top, right, bottom);
653    addPaint(paint);
654}
655
656void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
657            float rx, float ry, SkPaint* paint) {
658    addOp(DisplayList::DrawRoundRect);
659    addBounds(left, top, right, bottom);
660    addPoint(rx, ry);
661    addPaint(paint);
662}
663
664void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
665    addOp(DisplayList::DrawCircle);
666    addPoint(x, y);
667    addFloat(radius);
668    addPaint(paint);
669}
670
671void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
672        SkPaint* paint) {
673    addOp(DisplayList::DrawOval);
674    addBounds(left, top, right, bottom);
675    addPaint(paint);
676}
677
678void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
679    addOp(DisplayList::DrawPath);
680    addPath(path);
681    addPaint(paint);
682}
683
684void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
685    addOp(DisplayList::DrawLines);
686    addFloats(points, count);
687    addPaint(paint);
688}
689
690void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
691        float x, float y, SkPaint* paint) {
692    addOp(DisplayList::DrawText);
693    addText(text, bytesCount);
694    addInt(count);
695    addPoint(x, y);
696    addPaint(paint);
697}
698
699void DisplayListRenderer::resetShader() {
700    addOp(DisplayList::ResetShader);
701}
702
703void DisplayListRenderer::setupShader(SkiaShader* shader) {
704    addOp(DisplayList::SetupShader);
705    addShader(shader);
706}
707
708void DisplayListRenderer::resetColorFilter() {
709    addOp(DisplayList::ResetColorFilter);
710}
711
712void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
713    addOp(DisplayList::SetupColorFilter);
714    addColorFilter(filter);
715}
716
717void DisplayListRenderer::resetShadow() {
718    addOp(DisplayList::ResetShadow);
719}
720
721void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
722    addOp(DisplayList::SetupShadow);
723    addFloat(radius);
724    addPoint(dx, dy);
725    addInt(color);
726}
727
728}; // namespace uirenderer
729}; // namespace android
730