DisplayListRenderer.cpp revision d98aa2de9ab18e09c2be1997f41212740f51f6e6
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    Caches& caches = Caches::getInstance();
104
105    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
106    for (size_t i = 0; i < bitmapResources.size(); i++) {
107        SkBitmap* resource = bitmapResources.itemAt(i);
108        mBitmapResources.add(resource);
109        caches.resourceCache.incrementRefcount(resource);
110    }
111
112    const Vector<SkiaShader*> &shaderResources = recorder.getShaderResources();
113    for (size_t i = 0; i < shaderResources.size(); i++) {
114        SkiaShader* resource = shaderResources.itemAt(i);
115        mShaderResources.add(resource);
116        caches.resourceCache.incrementRefcount(resource);
117    }
118
119    const Vector<SkPaint*> &paints = recorder.getPaints();
120    for (size_t i = 0; i < paints.size(); i++) {
121        mPaints.add(paints.itemAt(i));
122    }
123
124    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
125    for (size_t i = 0; i < matrices.size(); i++) {
126        mMatrices.add(matrices.itemAt(i));
127    }
128
129    mPathHeap = recorder.mPathHeap;
130    mPathHeap->safeRef();
131}
132
133DisplayList::~DisplayList() {
134    sk_free((void*) mReader.base());
135
136    Caches& caches = Caches::getInstance();
137
138    for (size_t i = 0; i < mBitmapResources.size(); i++) {
139        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
140    }
141    mBitmapResources.clear();
142
143    for (size_t i = 0; i < mShaderResources.size(); i++) {
144        caches.resourceCache.decrementRefcount(mShaderResources.itemAt(i));
145    }
146    mShaderResources.clear();
147
148    for (size_t i = 0; i < mPaints.size(); i++) {
149        delete mPaints.itemAt(i);
150    }
151    mPaints.clear();
152
153    for (size_t i = 0; i < mMatrices.size(); i++) {
154        delete  mMatrices.itemAt(i);
155    }
156    mMatrices.clear();
157
158    mPathHeap->safeUnref();
159}
160
161void DisplayList::init() {
162    mPathHeap = NULL;
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* colors = NULL;
240                uint32_t xDivsCount = 0;
241                uint32_t yDivsCount = 0;
242                int8_t numColors = 0;
243
244                SkBitmap* bitmap = getBitmap();
245
246                xDivs = getInts(xDivsCount);
247                yDivs = getInts(yDivsCount);
248                colors = getUInts(numColors);
249
250                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
251                        numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
252            }
253            break;
254            case DrawColor: {
255                renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
256            }
257            break;
258            case DrawRect: {
259                renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
260            }
261            break;
262            case DrawPath: {
263                renderer.drawPath(getPath(), getPaint());
264            }
265            break;
266            case DrawLines: {
267                int count = 0;
268                float* points = getFloats(count);
269                renderer.drawLines(points, count, getPaint());
270            }
271            break;
272            case DrawText: {
273                getText(&text);
274                renderer.drawText(text.text(), text.length(), getInt(),
275                        getFloat(), getFloat(), getPaint());
276            }
277            break;
278            case ResetShader: {
279                renderer.resetShader();
280            }
281            break;
282            case SetupShader: {
283                renderer.setupShader(getShader());
284            }
285            break;
286            case ResetColorFilter: {
287                renderer.resetColorFilter();
288            }
289            break;
290            case SetupColorFilter: {
291                // TODO: Implement
292            }
293            break;
294            case ResetShadow: {
295                renderer.resetShadow();
296            }
297            break;
298            case SetupShadow: {
299                renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
300            }
301            break;
302        }
303    }
304}
305
306///////////////////////////////////////////////////////////////////////////////
307// Base structure
308///////////////////////////////////////////////////////////////////////////////
309
310DisplayListRenderer::DisplayListRenderer():
311        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
312    mPathHeap = NULL;
313}
314
315DisplayListRenderer::~DisplayListRenderer() {
316    reset();
317}
318
319void DisplayListRenderer::reset() {
320    if (mPathHeap) {
321        mPathHeap->unref();
322        mPathHeap = NULL;
323    }
324
325    mWriter.reset();
326    mHeap.reset();
327
328    mRCRecorder.reset();
329    mTFRecorder.reset();
330
331    Caches& caches = Caches::getInstance();
332    for (size_t i = 0; i < mBitmapResources.size(); i++) {
333        SkBitmap* resource = mBitmapResources.itemAt(i);
334        caches.resourceCache.decrementRefcount(resource);
335    }
336    mBitmapResources.clear();
337
338    for (size_t i = 0; i < mShaderResources.size(); i++) {
339        SkiaShader* resource = mShaderResources.itemAt(i);
340        caches.resourceCache.decrementRefcount(resource);
341    }
342    mShaderResources.clear();
343
344    mPaints.clear();
345    mPaintMap.clear();
346    mMatrices.clear();
347}
348
349///////////////////////////////////////////////////////////////////////////////
350// Operations
351///////////////////////////////////////////////////////////////////////////////
352
353void DisplayListRenderer::setViewport(int width, int height) {
354    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
355
356    mWidth = width;
357    mHeight = height;
358}
359
360void DisplayListRenderer::prepare(bool opaque) {
361    mSnapshot = new Snapshot(mFirstSnapshot,
362            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
363    mSaveCount = 1;
364    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
365}
366
367void DisplayListRenderer::acquireContext() {
368    addOp(DisplayList::AcquireContext);
369    OpenGLRenderer::acquireContext();
370}
371
372void DisplayListRenderer::releaseContext() {
373    addOp(DisplayList::ReleaseContext);
374    OpenGLRenderer::releaseContext();
375}
376
377int DisplayListRenderer::save(int flags) {
378    addOp(DisplayList::Save);
379    addInt(flags);
380    return OpenGLRenderer::save(flags);
381}
382
383void DisplayListRenderer::restore() {
384    addOp(DisplayList::Restore);
385    OpenGLRenderer::restore();
386}
387
388void DisplayListRenderer::restoreToCount(int saveCount) {
389    addOp(DisplayList::RestoreToCount);
390    addInt(saveCount);
391    OpenGLRenderer::restoreToCount(saveCount);
392}
393
394int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
395        SkPaint* p, int flags) {
396    addOp(DisplayList::SaveLayer);
397    addBounds(left, top, right, bottom);
398    addPaint(p);
399    addInt(flags);
400    return OpenGLRenderer::save(flags);
401}
402
403void DisplayListRenderer::translate(float dx, float dy) {
404    addOp(DisplayList::Translate);
405    addPoint(dx, dy);
406    OpenGLRenderer::translate(dx, dy);
407}
408
409void DisplayListRenderer::rotate(float degrees) {
410    addOp(DisplayList::Rotate);
411    addFloat(degrees);
412    OpenGLRenderer::rotate(degrees);
413}
414
415void DisplayListRenderer::scale(float sx, float sy) {
416    addOp(DisplayList::Scale);
417    addPoint(sx, sy);
418    OpenGLRenderer::scale(sx, sy);
419}
420
421void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
422    addOp(DisplayList::SetMatrix);
423    addMatrix(matrix);
424    OpenGLRenderer::setMatrix(matrix);
425}
426
427void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
428    addOp(DisplayList::ConcatMatrix);
429    addMatrix(matrix);
430    OpenGLRenderer::concatMatrix(matrix);
431}
432
433bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
434        SkRegion::Op op) {
435    addOp(DisplayList::ClipRect);
436    addBounds(left, top, right, bottom);
437    addInt(op);
438    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
439}
440
441void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
442        SkPaint* paint) {
443    addOp(DisplayList::DrawBitmap);
444    addBitmap(bitmap);
445    addPoint(left, top);
446    addPaint(paint);
447}
448
449void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
450        SkPaint* paint) {
451    addOp(DisplayList::DrawBitmapMatrix);
452    addBitmap(bitmap);
453    addMatrix(matrix);
454    addPaint(paint);
455}
456
457void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
458        float srcRight, float srcBottom, float dstLeft, float dstTop,
459        float dstRight, float dstBottom, SkPaint* paint) {
460    addOp(DisplayList::DrawBitmapRect);
461    addBitmap(bitmap);
462    addBounds(srcLeft, srcTop, srcRight, srcBottom);
463    addBounds(dstLeft, dstTop, dstRight, dstBottom);
464    addPaint(paint);
465}
466
467void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
468        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
469        float left, float top, float right, float bottom, SkPaint* paint) {
470    addOp(DisplayList::DrawPatch);
471    addBitmap(bitmap);
472    addInts(xDivs, width);
473    addInts(yDivs, height);
474    addUInts(colors, numColors);
475    addBounds(left, top, right, bottom);
476    addPaint(paint);
477}
478
479void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
480    addOp(DisplayList::DrawColor);
481    addInt(color);
482    addInt(mode);
483}
484
485void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
486        SkPaint* paint) {
487    addOp(DisplayList::DrawRect);
488    addBounds(left, top, right, bottom);
489    addPaint(paint);
490}
491
492void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
493    addOp(DisplayList::DrawPath);
494    addPath(path);
495    addPaint(paint);
496}
497
498void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
499    addOp(DisplayList::DrawLines);
500    addFloats(points, count);
501    addPaint(paint);
502}
503
504void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
505        float x, float y, SkPaint* paint) {
506    addOp(DisplayList::DrawText);
507    addText(text, bytesCount);
508    addInt(count);
509    addPoint(x, y);
510    addPaint(paint);
511}
512
513void DisplayListRenderer::resetShader() {
514    addOp(DisplayList::ResetShader);
515    OpenGLRenderer::resetShader();
516}
517
518void DisplayListRenderer::setupShader(SkiaShader* shader) {
519    addOp(DisplayList::SetupShader);
520    addShader(shader);
521}
522
523void DisplayListRenderer::resetColorFilter() {
524    addOp(DisplayList::ResetColorFilter);
525    OpenGLRenderer::resetColorFilter();
526}
527
528void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
529    // TODO: Implement
530    OpenGLRenderer::setupColorFilter(filter);
531}
532
533void DisplayListRenderer::resetShadow() {
534    addOp(DisplayList::ResetShadow);
535    OpenGLRenderer::resetShadow();
536}
537
538void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
539    addOp(DisplayList::SetupShadow);
540    addFloat(radius);
541    addPoint(dx, dy);
542    addInt(color);
543    OpenGLRenderer::setupShadow(radius, dx, dy, color);
544}
545
546}; // namespace uirenderer
547}; // namespace android
548