DisplayListRenderer.cpp revision b051e895ccb696604349c6c5efe7c4747e1d1ab6
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// Display list
26///////////////////////////////////////////////////////////////////////////////
27
28DisplayList::DisplayList(const DisplayListRenderer& recorder) {
29    const SkWriter32& writer = recorder.writeStream();
30    init();
31
32    if (writer.size() == 0) {
33        return;
34    }
35
36    size_t size = writer.size();
37    void* buffer = sk_malloc_throw(size);
38    writer.flatten(buffer);
39    mReader.setMemory(buffer, size);
40
41    mRCPlayback.reset(&recorder.mRCRecorder);
42    mRCPlayback.setupBuffer(mReader);
43
44    mTFPlayback.reset(&recorder.mTFRecorder);
45    mTFPlayback.setupBuffer(mReader);
46
47    const SkTDArray<const SkFlatBitmap*>& bitmaps = recorder.getBitmaps();
48    mBitmapCount = bitmaps.count();
49    if (mBitmapCount > 0) {
50        mBitmaps = new SkBitmap[mBitmapCount];
51        for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin();
52                flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) {
53            const SkFlatBitmap* flatBitmap = *flatBitmapPtr;
54            int index = flatBitmap->index() - 1;
55            flatBitmap->unflatten(&mBitmaps[index], &mRCPlayback);
56        }
57    }
58
59    const SkTDArray<const SkFlatMatrix*>& matrices = recorder.getMatrices();
60    mMatrixCount = matrices.count();
61    if (mMatrixCount > 0) {
62        mMatrices = new SkMatrix[mMatrixCount];
63        for (const SkFlatMatrix** matrixPtr = matrices.begin();
64                matrixPtr != matrices.end(); matrixPtr++) {
65            const SkFlatMatrix* flatMatrix = *matrixPtr;
66            flatMatrix->unflatten(&mMatrices[flatMatrix->index() - 1]);
67        }
68    }
69
70    const SkTDArray<const SkFlatPaint*>& paints = recorder.getPaints();
71    mPaintCount = paints.count();
72    if (mPaintCount > 0) {
73        mPaints = new SkPaint[mPaintCount];
74        for (const SkFlatPaint** flatPaintPtr = paints.begin();
75                flatPaintPtr != paints.end(); flatPaintPtr++) {
76            const SkFlatPaint* flatPaint = *flatPaintPtr;
77            int index = flatPaint->index() - 1;
78            flatPaint->unflatten(&mPaints[index], &mRCPlayback, &mTFPlayback);
79        }
80    }
81
82    mPathHeap = recorder.mPathHeap;
83    mPathHeap->safeRef();
84}
85
86DisplayList::~DisplayList() {
87    sk_free((void*) mReader.base());
88
89    Caches& caches = Caches::getInstance();
90    for (int i = 0; i < mBitmapCount; i++) {
91        caches.textureCache.remove(&mBitmaps[i]);
92    }
93
94    delete[] mBitmaps;
95    delete[] mMatrices;
96    delete[] mPaints;
97
98    mPathHeap->safeUnref();
99}
100
101void DisplayList::init() {
102    mBitmaps = NULL;
103    mMatrices = NULL;
104    mPaints = NULL;
105    mPathHeap = NULL;
106    mBitmapCount = mMatrixCount = mPaintCount = 0;
107}
108
109void DisplayList::replay(OpenGLRenderer& renderer) {
110    TextContainer text;
111    mReader.rewind();
112
113    int saveCount = renderer.getSaveCount() - 1;
114
115    while (!mReader.eof()) {
116        switch (mReader.readInt()) {
117            case AcquireContext: {
118                renderer.acquireContext();
119            }
120            break;
121            case ReleaseContext: {
122                renderer.releaseContext();
123            }
124            break;
125            case Save: {
126                renderer.save(getInt());
127            }
128            break;
129            case Restore: {
130                renderer.restore();
131            }
132            break;
133            case RestoreToCount: {
134                renderer.restoreToCount(saveCount + getInt());
135            }
136            break;
137            case SaveLayer: {
138                renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
139                        getPaint(), getInt());
140            }
141            break;
142            case Translate: {
143                renderer.translate(getFloat(), getFloat());
144            }
145            break;
146            case Rotate: {
147                renderer.rotate(getFloat());
148            }
149            break;
150            case Scale: {
151                renderer.scale(getFloat(), getFloat());
152            }
153            break;
154            case SetMatrix: {
155                renderer.setMatrix(getMatrix());
156            }
157            break;
158            case ConcatMatrix: {
159                renderer.concatMatrix(getMatrix());
160            }
161            break;
162            case ClipRect: {
163                renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
164                        (SkRegion::Op) getInt());
165            }
166            break;
167            case DrawBitmap: {
168                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
169            }
170            break;
171            case DrawBitmapMatrix: {
172                renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
173            }
174            break;
175            case DrawBitmapRect: {
176                renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
177                        getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
178            }
179            break;
180            case DrawPatch: {
181                int32_t* xDivs = NULL;
182                int32_t* yDivs = NULL;
183                uint32_t xDivsCount = 0;
184                uint32_t yDivsCount = 0;
185
186                SkBitmap* bitmap = getBitmap();
187
188                xDivs = getInts(xDivsCount);
189                yDivs = getInts(yDivsCount);
190
191                renderer.drawPatch(bitmap, xDivs, yDivs, xDivsCount, yDivsCount,
192                        getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
193            }
194            break;
195            case DrawColor: {
196                renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
197            }
198            break;
199            case DrawRect: {
200                renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
201            }
202            break;
203            case DrawPath: {
204                renderer.drawPath(getPath(), getPaint());
205            }
206            break;
207            case DrawLines: {
208                int count = 0;
209                float* points = getFloats(count);
210                renderer.drawLines(points, count, getPaint());
211            }
212            break;
213            case DrawText: {
214                getText(&text);
215                renderer.drawText(text.text(), text.length(), getInt(),
216                        getFloat(), getFloat(), getPaint());
217            }
218            break;
219            case ResetShader: {
220                renderer.resetShader();
221            }
222            break;
223            case SetupShader: {
224                // TODO: Implement
225            }
226            break;
227            case ResetColorFilter: {
228                renderer.resetColorFilter();
229            }
230            break;
231            case SetupColorFilter: {
232                // TODO: Implement
233            }
234            break;
235            case ResetShadow: {
236                renderer.resetShadow();
237            }
238            break;
239            case SetupShadow: {
240                renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
241            }
242            break;
243        }
244    }
245}
246
247///////////////////////////////////////////////////////////////////////////////
248// Base structure
249///////////////////////////////////////////////////////////////////////////////
250
251DisplayListRenderer::DisplayListRenderer():
252        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
253    mBitmapIndex = mMatrixIndex = mPaintIndex = 1;
254    mPathHeap = NULL;
255}
256
257DisplayListRenderer::~DisplayListRenderer() {
258    reset();
259}
260
261void DisplayListRenderer::reset() {
262    if (mPathHeap) {
263        mPathHeap->unref();
264        mPathHeap = NULL;
265    }
266
267    mBitmaps.reset();
268    mMatrices.reset();
269    mPaints.reset();
270
271    mWriter.reset();
272    mHeap.reset();
273
274    mRCRecorder.reset();
275    mTFRecorder.reset();
276}
277
278///////////////////////////////////////////////////////////////////////////////
279// Operations
280///////////////////////////////////////////////////////////////////////////////
281
282void DisplayListRenderer::setViewport(int width, int height) {
283    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
284
285    mWidth = width;
286    mHeight = height;
287}
288
289void DisplayListRenderer::prepare() {
290    mSnapshot = new Snapshot(mFirstSnapshot,
291            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
292    mSaveCount = 1;
293    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
294}
295
296void DisplayListRenderer::acquireContext() {
297    addOp(DisplayList::AcquireContext);
298    OpenGLRenderer::acquireContext();
299}
300
301void DisplayListRenderer::releaseContext() {
302    addOp(DisplayList::ReleaseContext);
303    OpenGLRenderer::releaseContext();
304}
305
306int DisplayListRenderer::save(int flags) {
307    addOp(DisplayList::Save);
308    addInt(flags);
309    return OpenGLRenderer::save(flags);
310}
311
312void DisplayListRenderer::restore() {
313    addOp(DisplayList::Restore);
314    OpenGLRenderer::restore();
315}
316
317void DisplayListRenderer::restoreToCount(int saveCount) {
318    addOp(DisplayList::RestoreToCount);
319    addInt(saveCount);
320    OpenGLRenderer::restoreToCount(saveCount);
321}
322
323int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
324        const SkPaint* p, int flags) {
325    addOp(DisplayList::SaveLayer);
326    addBounds(left, top, right, bottom);
327    addPaint(p);
328    addInt(flags);
329    return OpenGLRenderer::save(flags);
330}
331
332void DisplayListRenderer::translate(float dx, float dy) {
333    addOp(DisplayList::Translate);
334    addPoint(dx, dy);
335    OpenGLRenderer::translate(dx, dy);
336}
337
338void DisplayListRenderer::rotate(float degrees) {
339    addOp(DisplayList::Rotate);
340    addFloat(degrees);
341    OpenGLRenderer::rotate(degrees);
342}
343
344void DisplayListRenderer::scale(float sx, float sy) {
345    addOp(DisplayList::Scale);
346    addPoint(sx, sy);
347    OpenGLRenderer::scale(sx, sy);
348}
349
350void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
351    addOp(DisplayList::SetMatrix);
352    addMatrix(matrix);
353    OpenGLRenderer::setMatrix(matrix);
354}
355
356void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
357    addOp(DisplayList::ConcatMatrix);
358    addMatrix(matrix);
359    OpenGLRenderer::concatMatrix(matrix);
360}
361
362bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
363        SkRegion::Op op) {
364    addOp(DisplayList::ClipRect);
365    addBounds(left, top, right, bottom);
366    addInt(op);
367    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
368}
369
370void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
371        const SkPaint* paint) {
372    addOp(DisplayList::DrawBitmap);
373    addBitmap(bitmap);
374    addPoint(left, top);
375    addPaint(paint);
376}
377
378void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
379        const SkPaint* paint) {
380    addOp(DisplayList::DrawBitmapMatrix);
381    addBitmap(bitmap);
382    addMatrix(matrix);
383    addPaint(paint);
384}
385
386void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
387        float srcRight, float srcBottom, float dstLeft, float dstTop,
388        float dstRight, float dstBottom, const SkPaint* paint) {
389    addOp(DisplayList::DrawBitmapRect);
390    addBitmap(bitmap);
391    addBounds(srcLeft, srcTop, srcRight, srcBottom);
392    addBounds(dstLeft, dstTop, dstRight, dstBottom);
393    addPaint(paint);
394}
395
396void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
397        uint32_t width, uint32_t height, float left, float top, float right, float bottom,
398        const SkPaint* paint) {
399    addOp(DisplayList::DrawPatch);
400    addBitmap(bitmap);
401    addInts(xDivs, width);
402    addInts(yDivs, height);
403    addBounds(left, top, right, bottom);
404    addPaint(paint);
405}
406
407void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
408    addOp(DisplayList::DrawColor);
409    addInt(color);
410    addInt(mode);
411}
412
413void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
414        const SkPaint* paint) {
415    addOp(DisplayList::DrawRect);
416    addBounds(left, top, right, bottom);
417    addPaint(paint);
418}
419
420void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
421    addOp(DisplayList::DrawPath);
422    addPath(path);
423    addPaint(paint);
424}
425
426void DisplayListRenderer::drawLines(float* points, int count, const SkPaint* paint) {
427    addOp(DisplayList::DrawLines);
428    addFloats(points, count);
429    addPaint(paint);
430}
431
432void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
433        float x, float y, SkPaint* paint) {
434    addOp(DisplayList::DrawText);
435    addText(text, bytesCount);
436    addInt(count);
437    addPoint(x, y);
438    addPaint(paint);
439}
440
441void DisplayListRenderer::resetShader() {
442    addOp(DisplayList::ResetShader);
443    OpenGLRenderer::resetShader();
444}
445
446void DisplayListRenderer::setupShader(SkiaShader* shader) {
447    // TODO: Implement
448    OpenGLRenderer::setupShader(shader);
449}
450
451void DisplayListRenderer::resetColorFilter() {
452    addOp(DisplayList::ResetColorFilter);
453    OpenGLRenderer::resetColorFilter();
454}
455
456void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
457    // TODO: Implement
458    OpenGLRenderer::setupColorFilter(filter);
459}
460
461void DisplayListRenderer::resetShadow() {
462    addOp(DisplayList::ResetShadow);
463    OpenGLRenderer::resetShadow();
464}
465
466void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
467    addOp(DisplayList::SetupShadow);
468    addFloat(radius);
469    addPoint(dx, dy);
470    addInt(color);
471    OpenGLRenderer::setupShadow(radius, dx, dy, color);
472}
473
474///////////////////////////////////////////////////////////////////////////////
475// Recording management
476///////////////////////////////////////////////////////////////////////////////
477
478int DisplayListRenderer::find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint) {
479    if (paint == NULL) {
480        return 0;
481    }
482
483    SkFlatPaint* flat = SkFlatPaint::Flatten(&mHeap, *paint, mPaintIndex,
484            &mRCRecorder, &mTFRecorder);
485    int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
486            paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
487    if (index >= 0) {
488        (void) mHeap.unalloc(flat);
489        return paints[index]->index();
490    }
491
492    index = ~index;
493    *paints.insert(index) = flat;
494    return mPaintIndex++;
495}
496
497int DisplayListRenderer::find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix) {
498    if (matrix == NULL) {
499        return 0;
500    }
501
502    SkFlatMatrix* flat = SkFlatMatrix::Flatten(&mHeap, *matrix, mMatrixIndex);
503    int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
504            matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
505    if (index >= 0) {
506        (void) mHeap.unalloc(flat);
507        return matrices[index]->index();
508    }
509    index = ~index;
510    *matrices.insert(index) = flat;
511    return mMatrixIndex++;
512}
513
514int DisplayListRenderer::find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap) {
515    SkFlatBitmap* flat = SkFlatBitmap::Flatten(&mHeap, bitmap, mBitmapIndex, &mRCRecorder);
516    int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
517            bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
518    if (index >= 0) {
519        (void) mHeap.unalloc(flat);
520        return bitmaps[index]->index();
521    }
522    index = ~index;
523    *bitmaps.insert(index) = flat;
524    return mBitmapIndex++;
525}
526
527}; // namespace uirenderer
528}; // namespace android
529