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