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