• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <SkCamera.h>
20 #include <SkCanvas.h>
21 
22 #include <private/hwui/DrawGlInfo.h>
23 
24 #include "DisplayList.h"
25 #include "DeferredDisplayList.h"
26 #include "DisplayListLogBuffer.h"
27 #include "DisplayListOp.h"
28 #include "DisplayListRenderer.h"
29 #include "Caches.h"
30 
31 namespace android {
32 namespace uirenderer {
33 
DisplayListRenderer()34 DisplayListRenderer::DisplayListRenderer():
35         mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData),
36         mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false),
37         mHasDrawOps(false), mFunctorCount(0) {
38 }
39 
~DisplayListRenderer()40 DisplayListRenderer::~DisplayListRenderer() {
41     reset();
42 }
43 
reset()44 void DisplayListRenderer::reset() {
45     mDisplayListData = new DisplayListData();
46     mCaches.resourceCache.lock();
47 
48     for (size_t i = 0; i < mBitmapResources.size(); i++) {
49         mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
50     }
51 
52     for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
53         mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
54     }
55 
56     for (size_t i = 0; i < mFilterResources.size(); i++) {
57         mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
58     }
59 
60     for (size_t i = 0; i < mPatchResources.size(); i++) {
61         mCaches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i));
62     }
63 
64     for (size_t i = 0; i < mShaders.size(); i++) {
65         mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
66     }
67 
68     for (size_t i = 0; i < mSourcePaths.size(); i++) {
69         mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
70     }
71 
72     for (size_t i = 0; i < mLayers.size(); i++) {
73         mCaches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i));
74     }
75 
76     mCaches.resourceCache.unlock();
77 
78     mBitmapResources.clear();
79     mOwnedBitmapResources.clear();
80     mFilterResources.clear();
81     mPatchResources.clear();
82     mSourcePaths.clear();
83 
84     mShaders.clear();
85     mShaderMap.clear();
86 
87     mPaints.clear();
88     mPaintMap.clear();
89 
90     mRegions.clear();
91     mRegionMap.clear();
92 
93     mPaths.clear();
94     mPathMap.clear();
95 
96     mMatrices.clear();
97 
98     mLayers.clear();
99 
100     mHasDrawOps = false;
101     mFunctorCount = 0;
102 }
103 
104 ///////////////////////////////////////////////////////////////////////////////
105 // Operations
106 ///////////////////////////////////////////////////////////////////////////////
107 
getDisplayList(DisplayList * displayList)108 DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
109     if (!displayList) {
110         displayList = new DisplayList(*this);
111     } else {
112         displayList->initFromDisplayListRenderer(*this, true);
113     }
114     displayList->setRenderable(mHasDrawOps);
115     return displayList;
116 }
117 
isDeferred()118 bool DisplayListRenderer::isDeferred() {
119     return true;
120 }
121 
setViewport(int width,int height)122 void DisplayListRenderer::setViewport(int width, int height) {
123     mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
124 
125     mWidth = width;
126     mHeight = height;
127 }
128 
prepareDirty(float left,float top,float right,float bottom,bool opaque)129 status_t DisplayListRenderer::prepareDirty(float left, float top,
130         float right, float bottom, bool opaque) {
131     mSnapshot = new Snapshot(mFirstSnapshot,
132             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
133     mSaveCount = 1;
134 
135     mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
136     mDirtyClip = opaque;
137 
138     mRestoreSaveCount = -1;
139 
140     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
141 }
142 
finish()143 void DisplayListRenderer::finish() {
144     insertRestoreToCount();
145     insertTranslate();
146 }
147 
interrupt()148 void DisplayListRenderer::interrupt() {
149 }
150 
resume()151 void DisplayListRenderer::resume() {
152 }
153 
callDrawGLFunction(Functor * functor,Rect & dirty)154 status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
155     // Ignore dirty during recording, it matters only when we replay
156     addDrawOp(new (alloc()) DrawFunctorOp(functor));
157     mFunctorCount++;
158     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
159 }
160 
save(int flags)161 int DisplayListRenderer::save(int flags) {
162     addStateOp(new (alloc()) SaveOp(flags));
163     return OpenGLRenderer::save(flags);
164 }
165 
restore()166 void DisplayListRenderer::restore() {
167     if (mRestoreSaveCount < 0) {
168         restoreToCount(getSaveCount() - 1);
169         return;
170     }
171 
172     mRestoreSaveCount--;
173     insertTranslate();
174     OpenGLRenderer::restore();
175 }
176 
restoreToCount(int saveCount)177 void DisplayListRenderer::restoreToCount(int saveCount) {
178     mRestoreSaveCount = saveCount;
179     insertTranslate();
180     OpenGLRenderer::restoreToCount(saveCount);
181 }
182 
saveLayer(float left,float top,float right,float bottom,int alpha,SkXfermode::Mode mode,int flags)183 int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
184         int alpha, SkXfermode::Mode mode, int flags) {
185     addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, alpha, mode, flags));
186     return OpenGLRenderer::save(flags);
187 }
188 
translate(float dx,float dy)189 void DisplayListRenderer::translate(float dx, float dy) {
190     mHasTranslate = true;
191     mTranslateX += dx;
192     mTranslateY += dy;
193     insertRestoreToCount();
194     OpenGLRenderer::translate(dx, dy);
195 }
196 
rotate(float degrees)197 void DisplayListRenderer::rotate(float degrees) {
198     addStateOp(new (alloc()) RotateOp(degrees));
199     OpenGLRenderer::rotate(degrees);
200 }
201 
scale(float sx,float sy)202 void DisplayListRenderer::scale(float sx, float sy) {
203     addStateOp(new (alloc()) ScaleOp(sx, sy));
204     OpenGLRenderer::scale(sx, sy);
205 }
206 
skew(float sx,float sy)207 void DisplayListRenderer::skew(float sx, float sy) {
208     addStateOp(new (alloc()) SkewOp(sx, sy));
209     OpenGLRenderer::skew(sx, sy);
210 }
211 
setMatrix(SkMatrix * matrix)212 void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
213     matrix = refMatrix(matrix);
214     addStateOp(new (alloc()) SetMatrixOp(matrix));
215     OpenGLRenderer::setMatrix(matrix);
216 }
217 
concatMatrix(SkMatrix * matrix)218 void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
219     matrix = refMatrix(matrix);
220     addStateOp(new (alloc()) ConcatMatrixOp(matrix));
221     OpenGLRenderer::concatMatrix(matrix);
222 }
223 
clipRect(float left,float top,float right,float bottom,SkRegion::Op op)224 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
225         SkRegion::Op op) {
226     addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
227     return OpenGLRenderer::clipRect(left, top, right, bottom, op);
228 }
229 
clipPath(SkPath * path,SkRegion::Op op)230 bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) {
231     path = refPath(path);
232     addStateOp(new (alloc()) ClipPathOp(path, op));
233     return OpenGLRenderer::clipPath(path, op);
234 }
235 
clipRegion(SkRegion * region,SkRegion::Op op)236 bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
237     region = refRegion(region);
238     addStateOp(new (alloc()) ClipRegionOp(region, op));
239     return OpenGLRenderer::clipRegion(region, op);
240 }
241 
drawDisplayList(DisplayList * displayList,Rect & dirty,int32_t flags)242 status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
243         Rect& dirty, int32_t flags) {
244     // dirty is an out parameter and should not be recorded,
245     // it matters only when replaying the display list
246 
247     // TODO: To be safe, the display list should be ref-counted in the
248     //       resources cache, but we rely on the caller (UI toolkit) to
249     //       do the right thing for now
250 
251     addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags));
252     return DrawGlInfo::kStatusDone;
253 }
254 
drawLayer(Layer * layer,float x,float y)255 status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) {
256     layer = refLayer(layer);
257     addDrawOp(new (alloc()) DrawLayerOp(layer, x, y));
258     return DrawGlInfo::kStatusDone;
259 }
260 
drawBitmap(SkBitmap * bitmap,float left,float top,SkPaint * paint)261 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
262     bitmap = refBitmap(bitmap);
263     paint = refPaint(paint);
264 
265     addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint));
266     return DrawGlInfo::kStatusDone;
267 }
268 
drawBitmap(SkBitmap * bitmap,SkMatrix * matrix,SkPaint * paint)269 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
270     bitmap = refBitmap(bitmap);
271     matrix = refMatrix(matrix);
272     paint = refPaint(paint);
273 
274     addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint));
275     return DrawGlInfo::kStatusDone;
276 }
277 
drawBitmap(SkBitmap * bitmap,float srcLeft,float srcTop,float srcRight,float srcBottom,float dstLeft,float dstTop,float dstRight,float dstBottom,SkPaint * paint)278 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
279         float srcRight, float srcBottom, float dstLeft, float dstTop,
280         float dstRight, float dstBottom, SkPaint* paint) {
281     bitmap = refBitmap(bitmap);
282     paint = refPaint(paint);
283 
284     if (srcLeft == 0 && srcTop == 0 &&
285             srcRight == bitmap->width() && srcBottom == bitmap->height() &&
286             (srcBottom - srcTop == dstBottom - dstTop) &&
287             (srcRight - srcLeft == dstRight - dstLeft)) {
288         // transform simple rect to rect drawing case into position bitmap ops, since they merge
289         addDrawOp(new (alloc()) DrawBitmapOp(bitmap, dstLeft, dstTop, paint));
290         return DrawGlInfo::kStatusDone;
291     }
292 
293     addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
294                     srcLeft, srcTop, srcRight, srcBottom,
295                     dstLeft, dstTop, dstRight, dstBottom, paint));
296     return DrawGlInfo::kStatusDone;
297 }
298 
drawBitmapData(SkBitmap * bitmap,float left,float top,SkPaint * paint)299 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
300         SkPaint* paint) {
301     bitmap = refBitmapData(bitmap);
302     paint = refPaint(paint);
303 
304     addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint));
305     return DrawGlInfo::kStatusDone;
306 }
307 
drawBitmapMesh(SkBitmap * bitmap,int meshWidth,int meshHeight,float * vertices,int * colors,SkPaint * paint)308 status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
309         float* vertices, int* colors, SkPaint* paint) {
310     int count = (meshWidth + 1) * (meshHeight + 1) * 2;
311     bitmap = refBitmap(bitmap);
312     vertices = refBuffer<float>(vertices, count);
313     paint = refPaint(paint);
314     colors = refBuffer<int>(colors, count);
315 
316     addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight,
317                     vertices, colors, paint));
318     return DrawGlInfo::kStatusDone;
319 }
320 
drawPatch(SkBitmap * bitmap,Res_png_9patch * patch,float left,float top,float right,float bottom,SkPaint * paint)321 status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
322         float left, float top, float right, float bottom, SkPaint* paint) {
323     bitmap = refBitmap(bitmap);
324     patch = refPatch(patch);
325     paint = refPaint(paint);
326 
327     addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint));
328     return DrawGlInfo::kStatusDone;
329 }
330 
drawColor(int color,SkXfermode::Mode mode)331 status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
332     addDrawOp(new (alloc()) DrawColorOp(color, mode));
333     return DrawGlInfo::kStatusDone;
334 }
335 
drawRect(float left,float top,float right,float bottom,SkPaint * paint)336 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
337         SkPaint* paint) {
338     paint = refPaint(paint);
339     addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
340     return DrawGlInfo::kStatusDone;
341 }
342 
drawRoundRect(float left,float top,float right,float bottom,float rx,float ry,SkPaint * paint)343 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
344         float rx, float ry, SkPaint* paint) {
345     paint = refPaint(paint);
346     addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
347     return DrawGlInfo::kStatusDone;
348 }
349 
drawCircle(float x,float y,float radius,SkPaint * paint)350 status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
351     paint = refPaint(paint);
352     addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
353     return DrawGlInfo::kStatusDone;
354 }
355 
drawOval(float left,float top,float right,float bottom,SkPaint * paint)356 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
357         SkPaint* paint) {
358     paint = refPaint(paint);
359     addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
360     return DrawGlInfo::kStatusDone;
361 }
362 
drawArc(float left,float top,float right,float bottom,float startAngle,float sweepAngle,bool useCenter,SkPaint * paint)363 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
364         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
365     paint = refPaint(paint);
366     addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
367                     startAngle, sweepAngle, useCenter, paint));
368     return DrawGlInfo::kStatusDone;
369 }
370 
drawPath(SkPath * path,SkPaint * paint)371 status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
372     path = refPath(path);
373     paint = refPaint(paint);
374 
375     addDrawOp(new (alloc()) DrawPathOp(path, paint));
376     return DrawGlInfo::kStatusDone;
377 }
378 
drawLines(float * points,int count,SkPaint * paint)379 status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
380     points = refBuffer<float>(points, count);
381     paint = refPaint(paint);
382 
383     addDrawOp(new (alloc()) DrawLinesOp(points, count, paint));
384     return DrawGlInfo::kStatusDone;
385 }
386 
drawPoints(float * points,int count,SkPaint * paint)387 status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
388     points = refBuffer<float>(points, count);
389     paint = refPaint(paint);
390 
391     addDrawOp(new (alloc()) DrawPointsOp(points, count, paint));
392     return DrawGlInfo::kStatusDone;
393 }
394 
drawTextOnPath(const char * text,int bytesCount,int count,SkPath * path,float hOffset,float vOffset,SkPaint * paint)395 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
396         SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
397     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
398 
399     text = refText(text, bytesCount);
400     path = refPath(path);
401     paint = refPaint(paint);
402 
403     DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
404             hOffset, vOffset, paint);
405     addDrawOp(op);
406     return DrawGlInfo::kStatusDone;
407 }
408 
drawPosText(const char * text,int bytesCount,int count,const float * positions,SkPaint * paint)409 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
410         const float* positions, SkPaint* paint) {
411     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
412 
413     text = refText(text, bytesCount);
414     positions = refBuffer<float>(positions, count * 2);
415     paint = refPaint(paint);
416 
417     DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
418     addDrawOp(op);
419     return DrawGlInfo::kStatusDone;
420 }
421 
drawText(const char * text,int bytesCount,int count,float x,float y,const float * positions,SkPaint * paint,float totalAdvance,const Rect & bounds,DrawOpMode drawOpMode)422 status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
423         float x, float y, const float* positions, SkPaint* paint,
424         float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
425 
426     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
427 
428     text = refText(text, bytesCount);
429     positions = refBuffer<float>(positions, count * 2);
430     paint = refPaint(paint);
431 
432     DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count,
433             x, y, positions, paint, totalAdvance, bounds);
434     addDrawOp(op);
435     return DrawGlInfo::kStatusDone;
436 }
437 
drawRects(const float * rects,int count,SkPaint * paint)438 status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
439     if (count <= 0) return DrawGlInfo::kStatusDone;
440 
441     rects = refBuffer<float>(rects, count);
442     paint = refPaint(paint);
443     addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
444     return DrawGlInfo::kStatusDone;
445 }
446 
resetShader()447 void DisplayListRenderer::resetShader() {
448     addStateOp(new (alloc()) ResetShaderOp());
449 }
450 
setupShader(SkiaShader * shader)451 void DisplayListRenderer::setupShader(SkiaShader* shader) {
452     shader = refShader(shader);
453     addStateOp(new (alloc()) SetupShaderOp(shader));
454 }
455 
resetColorFilter()456 void DisplayListRenderer::resetColorFilter() {
457     addStateOp(new (alloc()) ResetColorFilterOp());
458 }
459 
setupColorFilter(SkiaColorFilter * filter)460 void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
461     filter = refColorFilter(filter);
462     addStateOp(new (alloc()) SetupColorFilterOp(filter));
463 }
464 
resetShadow()465 void DisplayListRenderer::resetShadow() {
466     addStateOp(new (alloc()) ResetShadowOp());
467     OpenGLRenderer::resetShadow();
468 }
469 
setupShadow(float radius,float dx,float dy,int color)470 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
471     addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color));
472     OpenGLRenderer::setupShadow(radius, dx, dy, color);
473 }
474 
resetPaintFilter()475 void DisplayListRenderer::resetPaintFilter() {
476     addStateOp(new (alloc()) ResetPaintFilterOp());
477 }
478 
setupPaintFilter(int clearBits,int setBits)479 void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
480     addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits));
481 }
482 
insertRestoreToCount()483 void DisplayListRenderer::insertRestoreToCount() {
484     if (mRestoreSaveCount >= 0) {
485         DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount);
486         mDisplayListData->displayListOps.add(op);
487         mRestoreSaveCount = -1;
488     }
489 }
490 
insertTranslate()491 void DisplayListRenderer::insertTranslate() {
492     if (mHasTranslate) {
493         if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
494             DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY);
495             mDisplayListData->displayListOps.add(op);
496             mTranslateX = mTranslateY = 0.0f;
497         }
498         mHasTranslate = false;
499     }
500 }
501 
addStateOp(StateOp * op)502 void DisplayListRenderer::addStateOp(StateOp* op) {
503     addOpInternal(op);
504 }
505 
addDrawOp(DrawOp * op)506 void DisplayListRenderer::addDrawOp(DrawOp* op) {
507     Rect localBounds;
508     if (op->getLocalBounds(mDrawModifiers, localBounds)) {
509         bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
510                 localBounds.right, localBounds.bottom);
511         op->setQuickRejected(rejected);
512     }
513 
514     mHasDrawOps = true;
515     addOpInternal(op);
516 }
517 
518 }; // namespace uirenderer
519 }; // namespace android
520