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