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