• 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 
21 #include <private/hwui/DrawGlInfo.h>
22 
23 #include "DisplayListLogBuffer.h"
24 #include "DisplayListRenderer.h"
25 #include "Caches.h"
26 
27 namespace android {
28 namespace uirenderer {
29 
30 ///////////////////////////////////////////////////////////////////////////////
31 // Display list
32 ///////////////////////////////////////////////////////////////////////////////
33 
34 const char* DisplayList::OP_NAMES[] = {
35     "Save",
36     "Restore",
37     "RestoreToCount",
38     "SaveLayer",
39     "SaveLayerAlpha",
40     "Translate",
41     "Rotate",
42     "Scale",
43     "Skew",
44     "SetMatrix",
45     "ConcatMatrix",
46     "ClipRect",
47     "DrawDisplayList",
48     "DrawLayer",
49     "DrawBitmap",
50     "DrawBitmapMatrix",
51     "DrawBitmapRect",
52     "DrawBitmapData",
53     "DrawBitmapMesh",
54     "DrawPatch",
55     "DrawColor",
56     "DrawRect",
57     "DrawRoundRect",
58     "DrawCircle",
59     "DrawOval",
60     "DrawArc",
61     "DrawPath",
62     "DrawLines",
63     "DrawPoints",
64     "DrawText",
65     "DrawTextOnPath",
66     "DrawPosText",
67     "ResetShader",
68     "SetupShader",
69     "ResetColorFilter",
70     "SetupColorFilter",
71     "ResetShadow",
72     "SetupShadow",
73     "ResetPaintFilter",
74     "SetupPaintFilter",
75     "DrawGLFunction"
76 };
77 
outputLogBuffer(int fd)78 void DisplayList::outputLogBuffer(int fd) {
79     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
80     if (logBuffer.isEmpty()) {
81         return;
82     }
83 
84     FILE *file = fdopen(fd, "a");
85 
86     fprintf(file, "\nRecent DisplayList operations\n");
87     logBuffer.outputCommands(file, OP_NAMES);
88 
89     String8 cachesLog;
90     Caches::getInstance().dumpMemoryUsage(cachesLog);
91     fprintf(file, "\nCaches:\n%s", cachesLog.string());
92     fprintf(file, "\n");
93 
94     fflush(file);
95 }
96 
DisplayList(const DisplayListRenderer & recorder)97 DisplayList::DisplayList(const DisplayListRenderer& recorder) :
98     mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
99     mStaticMatrix(NULL), mAnimationMatrix(NULL) {
100 
101     initFromDisplayListRenderer(recorder);
102 }
103 
~DisplayList()104 DisplayList::~DisplayList() {
105     clearResources();
106 }
107 
initProperties()108 void DisplayList::initProperties() {
109     mLeft = 0;
110     mTop = 0;
111     mRight = 0;
112     mBottom = 0;
113     mClipChildren = true;
114     mAlpha = 1;
115     mMultipliedAlpha = 255;
116     mHasOverlappingRendering = true;
117     mTranslationX = 0;
118     mTranslationY = 0;
119     mRotation = 0;
120     mRotationX = 0;
121     mRotationY= 0;
122     mScaleX = 1;
123     mScaleY = 1;
124     mPivotX = 0;
125     mPivotY = 0;
126     mCameraDistance = 0;
127     mMatrixDirty = false;
128     mMatrixFlags = 0;
129     mPrevWidth = -1;
130     mPrevHeight = -1;
131     mWidth = 0;
132     mHeight = 0;
133     mPivotExplicitlySet = false;
134     mCaching = false;
135 }
136 
destroyDisplayListDeferred(DisplayList * displayList)137 void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
138     if (displayList) {
139         DISPLAY_LIST_LOGD("Deferring display list destruction");
140         Caches::getInstance().deleteDisplayListDeferred(displayList);
141     }
142 }
143 
clearResources()144 void DisplayList::clearResources() {
145     sk_free((void*) mReader.base());
146 
147     delete mTransformMatrix;
148     delete mTransformCamera;
149     delete mTransformMatrix3D;
150     delete mStaticMatrix;
151     delete mAnimationMatrix;
152     mTransformMatrix = NULL;
153     mTransformCamera = NULL;
154     mTransformMatrix3D = NULL;
155     mStaticMatrix = NULL;
156     mAnimationMatrix = NULL;
157 
158     Caches& caches = Caches::getInstance();
159 
160     for (size_t i = 0; i < mBitmapResources.size(); i++) {
161         caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
162     }
163     mBitmapResources.clear();
164 
165     for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
166         SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
167         caches.resourceCache.decrementRefcount(bitmap);
168         caches.resourceCache.destructor(bitmap);
169     }
170     mOwnedBitmapResources.clear();
171 
172     for (size_t i = 0; i < mFilterResources.size(); i++) {
173         caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
174     }
175     mFilterResources.clear();
176 
177     for (size_t i = 0; i < mShaders.size(); i++) {
178         caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
179         caches.resourceCache.destructor(mShaders.itemAt(i));
180     }
181     mShaders.clear();
182 
183     for (size_t i = 0; i < mPaints.size(); i++) {
184         delete mPaints.itemAt(i);
185     }
186     mPaints.clear();
187 
188     for (size_t i = 0; i < mPaths.size(); i++) {
189         SkPath* path = mPaths.itemAt(i);
190         caches.pathCache.remove(path);
191         delete path;
192     }
193     mPaths.clear();
194 
195     for (size_t i = 0; i < mSourcePaths.size(); i++) {
196         caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
197     }
198     mSourcePaths.clear();
199 
200     for (size_t i = 0; i < mMatrices.size(); i++) {
201         delete mMatrices.itemAt(i);
202     }
203     mMatrices.clear();
204 }
205 
initFromDisplayListRenderer(const DisplayListRenderer & recorder,bool reusing)206 void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
207     const SkWriter32& writer = recorder.writeStream();
208     init();
209 
210     if (writer.size() == 0) {
211         return;
212     }
213 
214     if (reusing) {
215         // re-using display list - clear out previous allocations
216         clearResources();
217     }
218     initProperties();
219 
220     mSize = writer.size();
221     void* buffer = sk_malloc_throw(mSize);
222     writer.flatten(buffer);
223     mReader.setMemory(buffer, mSize);
224 
225     Caches& caches = Caches::getInstance();
226 
227     const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
228     for (size_t i = 0; i < bitmapResources.size(); i++) {
229         SkBitmap* resource = bitmapResources.itemAt(i);
230         mBitmapResources.add(resource);
231         caches.resourceCache.incrementRefcount(resource);
232     }
233 
234     const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
235     for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
236         SkBitmap* resource = ownedBitmapResources.itemAt(i);
237         mOwnedBitmapResources.add(resource);
238         caches.resourceCache.incrementRefcount(resource);
239     }
240 
241     const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
242     for (size_t i = 0; i < filterResources.size(); i++) {
243         SkiaColorFilter* resource = filterResources.itemAt(i);
244         mFilterResources.add(resource);
245         caches.resourceCache.incrementRefcount(resource);
246     }
247 
248     const Vector<SkiaShader*>& shaders = recorder.getShaders();
249     for (size_t i = 0; i < shaders.size(); i++) {
250         SkiaShader* resource = shaders.itemAt(i);
251         mShaders.add(resource);
252         caches.resourceCache.incrementRefcount(resource);
253     }
254 
255     const Vector<SkPaint*>& paints = recorder.getPaints();
256     for (size_t i = 0; i < paints.size(); i++) {
257         mPaints.add(paints.itemAt(i));
258     }
259 
260     const Vector<SkPath*>& paths = recorder.getPaths();
261     for (size_t i = 0; i < paths.size(); i++) {
262         mPaths.add(paths.itemAt(i));
263     }
264 
265     const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
266     for (size_t i = 0; i < sourcePaths.size(); i++) {
267         mSourcePaths.add(sourcePaths.itemAt(i));
268         caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i));
269     }
270 
271     const Vector<SkMatrix*>& matrices = recorder.getMatrices();
272     for (size_t i = 0; i < matrices.size(); i++) {
273         mMatrices.add(matrices.itemAt(i));
274     }
275 }
276 
init()277 void DisplayList::init() {
278     mSize = 0;
279     mIsRenderable = true;
280 }
281 
getSize()282 size_t DisplayList::getSize() {
283     return mSize;
284 }
285 
286 /**
287  * This function is a simplified version of replay(), where we simply retrieve and log the
288  * display list. This function should remain in sync with the replay() function.
289  */
output(OpenGLRenderer & renderer,uint32_t level)290 void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
291     TextContainer text;
292 
293     uint32_t count = (level + 1) * 2;
294     char indent[count + 1];
295     for (uint32_t i = 0; i < count; i++) {
296         indent[i] = ' ';
297     }
298     indent[count] = '\0';
299     ALOGD("%sStart display list (%p, %s, render=%d)", (char*) indent + 2, this,
300             mName.string(), isRenderable());
301 
302     ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
303     int saveCount = renderer.getSaveCount() - 1;
304 
305     outputViewProperties(renderer, (char*) indent);
306     mReader.rewind();
307 
308     while (!mReader.eof()) {
309         int op = mReader.readInt();
310         if (op & OP_MAY_BE_SKIPPED_MASK) {
311             int skip = mReader.readInt();
312             ALOGD("%sSkip %d", (char*) indent, skip);
313             op &= ~OP_MAY_BE_SKIPPED_MASK;
314         }
315 
316         switch (op) {
317             case DrawGLFunction: {
318                 Functor *functor = (Functor *) getInt();
319                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
320             }
321             break;
322             case Save: {
323                 int rendererNum = getInt();
324                 ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
325             }
326             break;
327             case Restore: {
328                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
329             }
330             break;
331             case RestoreToCount: {
332                 int restoreCount = saveCount + getInt();
333                 ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
334             }
335             break;
336             case SaveLayer: {
337                 float f1 = getFloat();
338                 float f2 = getFloat();
339                 float f3 = getFloat();
340                 float f4 = getFloat();
341                 SkPaint* paint = getPaint(renderer);
342                 int flags = getInt();
343                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
344                         OP_NAMES[op], f1, f2, f3, f4, paint, flags);
345             }
346             break;
347             case SaveLayerAlpha: {
348                 float f1 = getFloat();
349                 float f2 = getFloat();
350                 float f3 = getFloat();
351                 float f4 = getFloat();
352                 int alpha = getInt();
353                 int flags = getInt();
354                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
355                         OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
356             }
357             break;
358             case Translate: {
359                 float f1 = getFloat();
360                 float f2 = getFloat();
361                 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
362             }
363             break;
364             case Rotate: {
365                 float rotation = getFloat();
366                 ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
367             }
368             break;
369             case Scale: {
370                 float sx = getFloat();
371                 float sy = getFloat();
372                 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
373             }
374             break;
375             case Skew: {
376                 float sx = getFloat();
377                 float sy = getFloat();
378                 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
379             }
380             break;
381             case SetMatrix: {
382                 SkMatrix* matrix = getMatrix();
383                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
384             }
385             break;
386             case ConcatMatrix: {
387                 SkMatrix* matrix = getMatrix();
388                 ALOGD("%s%s new concat %p: [%f, %f, %f]   [%f, %f, %f]   [%f, %f, %f]",
389                         (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1),
390                         matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5),
391                         matrix->get(6), matrix->get(7), matrix->get(8));
392             }
393             break;
394             case ClipRect: {
395                 float f1 = getFloat();
396                 float f2 = getFloat();
397                 float f3 = getFloat();
398                 float f4 = getFloat();
399                 int regionOp = getInt();
400                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
401                         f1, f2, f3, f4, regionOp);
402             }
403             break;
404             case DrawDisplayList: {
405                 DisplayList* displayList = getDisplayList();
406                 int32_t flags = getInt();
407                 ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
408                         displayList, mWidth, mHeight, flags, level + 1);
409                 renderer.outputDisplayList(displayList, level + 1);
410             }
411             break;
412             case DrawLayer: {
413                 Layer* layer = (Layer*) getInt();
414                 float x = getFloat();
415                 float y = getFloat();
416                 SkPaint* paint = getPaint(renderer);
417                 ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
418                         layer, x, y, paint);
419             }
420             break;
421             case DrawBitmap: {
422                 SkBitmap* bitmap = getBitmap();
423                 float x = getFloat();
424                 float y = getFloat();
425                 SkPaint* paint = getPaint(renderer);
426                 ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
427                         bitmap, x, y, paint);
428             }
429             break;
430             case DrawBitmapMatrix: {
431                 SkBitmap* bitmap = getBitmap();
432                 SkMatrix* matrix = getMatrix();
433                 SkPaint* paint = getPaint(renderer);
434                 ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
435                         bitmap, matrix, paint);
436             }
437             break;
438             case DrawBitmapRect: {
439                 SkBitmap* bitmap = getBitmap();
440                 float f1 = getFloat();
441                 float f2 = getFloat();
442                 float f3 = getFloat();
443                 float f4 = getFloat();
444                 float f5 = getFloat();
445                 float f6 = getFloat();
446                 float f7 = getFloat();
447                 float f8 = getFloat();
448                 SkPaint* paint = getPaint(renderer);
449                 ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
450                         (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
451             }
452             break;
453             case DrawBitmapData: {
454                 SkBitmap* bitmap = getBitmapData();
455                 float x = getFloat();
456                 float y = getFloat();
457                 SkPaint* paint = getPaint(renderer);
458                 ALOGD("%s%s %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], x, y, paint);
459             }
460             break;
461             case DrawBitmapMesh: {
462                 int verticesCount = 0;
463                 uint32_t colorsCount = 0;
464                 SkBitmap* bitmap = getBitmap();
465                 uint32_t meshWidth = getInt();
466                 uint32_t meshHeight = getInt();
467                 float* vertices = getFloats(verticesCount);
468                 bool hasColors = getInt();
469                 int* colors = hasColors ? getInts(colorsCount) : NULL;
470                 SkPaint* paint = getPaint(renderer);
471                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
472             }
473             break;
474             case DrawPatch: {
475                 int32_t* xDivs = NULL;
476                 int32_t* yDivs = NULL;
477                 uint32_t* colors = NULL;
478                 uint32_t xDivsCount = 0;
479                 uint32_t yDivsCount = 0;
480                 int8_t numColors = 0;
481                 SkBitmap* bitmap = getBitmap();
482                 xDivs = getInts(xDivsCount);
483                 yDivs = getInts(yDivsCount);
484                 colors = getUInts(numColors);
485                 float left = getFloat();
486                 float top = getFloat();
487                 float right = getFloat();
488                 float bottom = getFloat();
489                 SkPaint* paint = getPaint(renderer);
490                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
491                         left, top, right, bottom);
492             }
493             break;
494             case DrawColor: {
495                 int color = getInt();
496                 int xferMode = getInt();
497                 ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
498             }
499             break;
500             case DrawRect: {
501                 float f1 = getFloat();
502                 float f2 = getFloat();
503                 float f3 = getFloat();
504                 float f4 = getFloat();
505                 SkPaint* paint = getPaint(renderer);
506                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
507                         f1, f2, f3, f4, paint);
508             }
509             break;
510             case DrawRoundRect: {
511                 float f1 = getFloat();
512                 float f2 = getFloat();
513                 float f3 = getFloat();
514                 float f4 = getFloat();
515                 float f5 = getFloat();
516                 float f6 = getFloat();
517                 SkPaint* paint = getPaint(renderer);
518                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
519                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
520             }
521             break;
522             case DrawCircle: {
523                 float f1 = getFloat();
524                 float f2 = getFloat();
525                 float f3 = getFloat();
526                 SkPaint* paint = getPaint(renderer);
527                 ALOGD("%s%s %.2f, %.2f, %.2f, %p",
528                         (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
529             }
530             break;
531             case DrawOval: {
532                 float f1 = getFloat();
533                 float f2 = getFloat();
534                 float f3 = getFloat();
535                 float f4 = getFloat();
536                 SkPaint* paint = getPaint(renderer);
537                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
538                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
539             }
540             break;
541             case DrawArc: {
542                 float f1 = getFloat();
543                 float f2 = getFloat();
544                 float f3 = getFloat();
545                 float f4 = getFloat();
546                 float f5 = getFloat();
547                 float f6 = getFloat();
548                 int i1 = getInt();
549                 SkPaint* paint = getPaint(renderer);
550                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
551                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
552             }
553             break;
554             case DrawPath: {
555                 SkPath* path = getPath();
556                 SkPaint* paint = getPaint(renderer);
557                 ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
558             }
559             break;
560             case DrawLines: {
561                 int count = 0;
562                 float* points = getFloats(count);
563                 SkPaint* paint = getPaint(renderer);
564                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
565             }
566             break;
567             case DrawPoints: {
568                 int count = 0;
569                 float* points = getFloats(count);
570                 SkPaint* paint = getPaint(renderer);
571                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
572             }
573             break;
574             case DrawText: {
575                 getText(&text);
576                 int32_t count = getInt();
577                 float x = getFloat();
578                 float y = getFloat();
579                 SkPaint* paint = getPaint(renderer);
580                 float length = getFloat();
581                 ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
582                         text.text(), text.length(), count, x, y, paint, length);
583             }
584             break;
585             case DrawTextOnPath: {
586                 getText(&text);
587                 int32_t count = getInt();
588                 SkPath* path = getPath();
589                 float hOffset = getFloat();
590                 float vOffset = getFloat();
591                 SkPaint* paint = getPaint(renderer);
592                 ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
593                     text.text(), text.length(), count, paint);
594             }
595             break;
596             case DrawPosText: {
597                 getText(&text);
598                 int count = getInt();
599                 int positionsCount = 0;
600                 float* positions = getFloats(positionsCount);
601                 SkPaint* paint = getPaint(renderer);
602                 ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
603                         text.text(), text.length(), count, paint);
604             }
605             case ResetShader: {
606                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
607             }
608             break;
609             case SetupShader: {
610                 SkiaShader* shader = getShader();
611                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
612             }
613             break;
614             case ResetColorFilter: {
615                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
616             }
617             break;
618             case SetupColorFilter: {
619                 SkiaColorFilter *colorFilter = getColorFilter();
620                 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
621             }
622             break;
623             case ResetShadow: {
624                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
625             }
626             break;
627             case SetupShadow: {
628                 float radius = getFloat();
629                 float dx = getFloat();
630                 float dy = getFloat();
631                 int color = getInt();
632                 ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
633                         radius, dx, dy, color);
634             }
635             break;
636             case ResetPaintFilter: {
637                 ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
638             }
639             break;
640             case SetupPaintFilter: {
641                 int clearBits = getInt();
642                 int setBits = getInt();
643                 ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits);
644             }
645             break;
646             default:
647                 ALOGD("Display List error: op not handled: %s%s",
648                         (char*) indent, OP_NAMES[op]);
649                 break;
650         }
651     }
652     ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string());
653 }
654 
updateMatrix()655 void DisplayList::updateMatrix() {
656     if (mMatrixDirty) {
657         if (!mTransformMatrix) {
658             mTransformMatrix = new SkMatrix();
659         }
660         if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
661             mTransformMatrix->reset();
662         } else {
663             if (!mPivotExplicitlySet) {
664                 if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
665                     mPrevWidth = mWidth;
666                     mPrevHeight = mHeight;
667                     mPivotX = mPrevWidth / 2;
668                     mPivotY = mPrevHeight / 2;
669                 }
670             }
671             if ((mMatrixFlags & ROTATION_3D) == 0) {
672                 mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
673                 mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
674                 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
675             } else {
676                 if (!mTransformCamera) {
677                     mTransformCamera = new Sk3DView();
678                     mTransformMatrix3D = new SkMatrix();
679                 }
680                 mTransformMatrix->reset();
681                 mTransformCamera->save();
682                 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
683                 mTransformCamera->rotateX(mRotationX);
684                 mTransformCamera->rotateY(mRotationY);
685                 mTransformCamera->rotateZ(-mRotation);
686                 mTransformCamera->getMatrix(mTransformMatrix3D);
687                 mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
688                 mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
689                         mPivotY + mTranslationY);
690                 mTransformMatrix->postConcat(*mTransformMatrix3D);
691                 mTransformCamera->restore();
692             }
693         }
694         mMatrixDirty = false;
695     }
696 }
697 
outputViewProperties(OpenGLRenderer & renderer,char * indent)698 void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
699     updateMatrix();
700     if (mLeft != 0 || mTop != 0) {
701         ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
702     }
703     if (mStaticMatrix) {
704         ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
705                 indent, "ConcatMatrix (static)", mStaticMatrix,
706                 mStaticMatrix->get(0), mStaticMatrix->get(1),
707                 mStaticMatrix->get(2), mStaticMatrix->get(3),
708                 mStaticMatrix->get(4), mStaticMatrix->get(5),
709                 mStaticMatrix->get(6), mStaticMatrix->get(7),
710                 mStaticMatrix->get(8));
711     }
712     if (mAnimationMatrix) {
713         ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
714                 indent, "ConcatMatrix (animation)", mAnimationMatrix,
715                 mAnimationMatrix->get(0), mAnimationMatrix->get(1),
716                 mAnimationMatrix->get(2), mAnimationMatrix->get(3),
717                 mAnimationMatrix->get(4), mAnimationMatrix->get(5),
718                 mAnimationMatrix->get(6), mAnimationMatrix->get(7),
719                 mAnimationMatrix->get(8));
720     }
721     if (mMatrixFlags != 0) {
722         if (mMatrixFlags == TRANSLATION) {
723             ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
724         } else {
725             ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
726                     indent, "ConcatMatrix", mTransformMatrix,
727                     mTransformMatrix->get(0), mTransformMatrix->get(1),
728                     mTransformMatrix->get(2), mTransformMatrix->get(3),
729                     mTransformMatrix->get(4), mTransformMatrix->get(5),
730                     mTransformMatrix->get(6), mTransformMatrix->get(7),
731                     mTransformMatrix->get(8));
732         }
733     }
734     if (mAlpha < 1 && !mCaching) {
735         // TODO: should be able to store the size of a DL at record time and not
736         // have to pass it into this call. In fact, this information might be in the
737         // location/size info that we store with the new native transform data.
738         int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
739         if (mClipChildren) {
740             flags |= SkCanvas::kClipToLayer_SaveFlag;
741         }
742         ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
743                 (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
744                 mMultipliedAlpha, flags);
745     }
746     if (mClipChildren) {
747         ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
748                 (float) mRight - mLeft, (float) mBottom - mTop);
749     }
750 }
751 
setViewProperties(OpenGLRenderer & renderer,uint32_t level)752 void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
753 #if DEBUG_DISPLAY_LIST
754         uint32_t count = (level + 1) * 2;
755         char indent[count + 1];
756         for (uint32_t i = 0; i < count; i++) {
757             indent[i] = ' ';
758         }
759         indent[count] = '\0';
760 #endif
761     updateMatrix();
762     if (mLeft != 0 || mTop != 0) {
763         DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
764         renderer.translate(mLeft, mTop);
765     }
766     if (mStaticMatrix) {
767         DISPLAY_LIST_LOGD(
768                 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
769                 indent, "ConcatMatrix (static)", mStaticMatrix,
770                 mStaticMatrix->get(0), mStaticMatrix->get(1),
771                 mStaticMatrix->get(2), mStaticMatrix->get(3),
772                 mStaticMatrix->get(4), mStaticMatrix->get(5),
773                 mStaticMatrix->get(6), mStaticMatrix->get(7),
774                 mStaticMatrix->get(8));
775         renderer.concatMatrix(mStaticMatrix);
776     } else if (mAnimationMatrix) {
777         DISPLAY_LIST_LOGD(
778                 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
779                 indent, "ConcatMatrix (animation)", mAnimationMatrix,
780                 mAnimationMatrix->get(0), mAnimationMatrix->get(1),
781                 mAnimationMatrix->get(2), mAnimationMatrix->get(3),
782                 mAnimationMatrix->get(4), mAnimationMatrix->get(5),
783                 mAnimationMatrix->get(6), mAnimationMatrix->get(7),
784                 mAnimationMatrix->get(8));
785         renderer.concatMatrix(mAnimationMatrix);
786     }
787     if (mMatrixFlags != 0) {
788         if (mMatrixFlags == TRANSLATION) {
789             DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
790             renderer.translate(mTranslationX, mTranslationY);
791         } else {
792             DISPLAY_LIST_LOGD(
793                     "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
794                     indent, "ConcatMatrix", mTransformMatrix,
795                     mTransformMatrix->get(0), mTransformMatrix->get(1),
796                     mTransformMatrix->get(2), mTransformMatrix->get(3),
797                     mTransformMatrix->get(4), mTransformMatrix->get(5),
798                     mTransformMatrix->get(6), mTransformMatrix->get(7),
799                     mTransformMatrix->get(8));
800             renderer.concatMatrix(mTransformMatrix);
801         }
802     }
803     if (mAlpha < 1 && !mCaching) {
804         if (!mHasOverlappingRendering) {
805             DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
806             renderer.setAlpha(mAlpha);
807         } else {
808             // TODO: should be able to store the size of a DL at record time and not
809             // have to pass it into this call. In fact, this information might be in the
810             // location/size info that we store with the new native transform data.
811             int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
812             if (mClipChildren) {
813                 flags |= SkCanvas::kClipToLayer_SaveFlag;
814             }
815             DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
816                     (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
817                     mMultipliedAlpha, flags);
818             renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
819                     mMultipliedAlpha, flags);
820         }
821     }
822     if (mClipChildren) {
823         DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
824                 (float) mRight - mLeft, (float) mBottom - mTop);
825         renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
826                 SkRegion::kIntersect_Op);
827     }
828 }
829 
830 /**
831  * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
832  * in the output() function, since that function processes the same list of opcodes for the
833  * purposes of logging display list info for a given view.
834  */
replay(OpenGLRenderer & renderer,Rect & dirty,int32_t flags,uint32_t level)835 status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
836     status_t drawGlStatus = DrawGlInfo::kStatusDone;
837     TextContainer text;
838     mReader.rewind();
839 
840 #if DEBUG_DISPLAY_LIST
841     uint32_t count = (level + 1) * 2;
842     char indent[count + 1];
843     for (uint32_t i = 0; i < count; i++) {
844         indent[i] = ' ';
845     }
846     indent[count] = '\0';
847     Rect* clipRect = renderer.getClipRect();
848     DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
849             (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top,
850             clipRect->right, clipRect->bottom);
851 #endif
852 
853     renderer.startMark(mName.string());
854     int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
855     DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
856             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
857     setViewProperties(renderer, level);
858     if (renderer.quickReject(0, 0, mWidth, mHeight)) {
859         DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
860         renderer.restoreToCount(restoreTo);
861         renderer.endMark();
862         return drawGlStatus;
863     }
864 
865     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
866     int saveCount = renderer.getSaveCount() - 1;
867     while (!mReader.eof()) {
868         int op = mReader.readInt();
869         if (op & OP_MAY_BE_SKIPPED_MASK) {
870             int32_t skip = mReader.readInt();
871             if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) {
872                 mReader.skip(skip);
873                 DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent,
874                         OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip);
875                 continue;
876             } else {
877                 op &= ~OP_MAY_BE_SKIPPED_MASK;
878             }
879         }
880         logBuffer.writeCommand(level, op);
881 
882         switch (op) {
883             case DrawGLFunction: {
884                 Functor *functor = (Functor *) getInt();
885                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
886                 renderer.startMark("GL functor");
887                 drawGlStatus |= renderer.callDrawGLFunction(functor, dirty);
888                 renderer.endMark();
889             }
890             break;
891             case Save: {
892                 int32_t rendererNum = getInt();
893                 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
894                 renderer.save(rendererNum);
895             }
896             break;
897             case Restore: {
898                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
899                 renderer.restore();
900             }
901             break;
902             case RestoreToCount: {
903                 int32_t restoreCount = saveCount + getInt();
904                 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
905                 renderer.restoreToCount(restoreCount);
906             }
907             break;
908             case SaveLayer: {
909                 float f1 = getFloat();
910                 float f2 = getFloat();
911                 float f3 = getFloat();
912                 float f4 = getFloat();
913                 SkPaint* paint = getPaint(renderer);
914                 int32_t flags = getInt();
915                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
916                         OP_NAMES[op], f1, f2, f3, f4, paint, flags);
917                 renderer.saveLayer(f1, f2, f3, f4, paint, flags);
918             }
919             break;
920             case SaveLayerAlpha: {
921                 float f1 = getFloat();
922                 float f2 = getFloat();
923                 float f3 = getFloat();
924                 float f4 = getFloat();
925                 int32_t alpha = getInt();
926                 int32_t flags = getInt();
927                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
928                         OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
929                 renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
930             }
931             break;
932             case Translate: {
933                 float f1 = getFloat();
934                 float f2 = getFloat();
935                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
936                 renderer.translate(f1, f2);
937             }
938             break;
939             case Rotate: {
940                 float rotation = getFloat();
941                 DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
942                 renderer.rotate(rotation);
943             }
944             break;
945             case Scale: {
946                 float sx = getFloat();
947                 float sy = getFloat();
948                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
949                 renderer.scale(sx, sy);
950             }
951             break;
952             case Skew: {
953                 float sx = getFloat();
954                 float sy = getFloat();
955                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
956                 renderer.skew(sx, sy);
957             }
958             break;
959             case SetMatrix: {
960                 SkMatrix* matrix = getMatrix();
961                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
962                 renderer.setMatrix(matrix);
963             }
964             break;
965             case ConcatMatrix: {
966                 SkMatrix* matrix = getMatrix();
967                 DISPLAY_LIST_LOGD(
968                         "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
969                         (char*) indent, OP_NAMES[op], matrix,
970                         matrix->get(0), matrix->get(1), matrix->get(2),
971                         matrix->get(3), matrix->get(4), matrix->get(5),
972                         matrix->get(6), matrix->get(7), matrix->get(8));
973                 renderer.concatMatrix(matrix);
974             }
975             break;
976             case ClipRect: {
977                 float f1 = getFloat();
978                 float f2 = getFloat();
979                 float f3 = getFloat();
980                 float f4 = getFloat();
981                 int32_t regionOp = getInt();
982                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
983                         f1, f2, f3, f4, regionOp);
984                 renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
985             }
986             break;
987             case DrawDisplayList: {
988                 DisplayList* displayList = getDisplayList();
989                 int32_t flags = getInt();
990                 DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
991                         displayList, mWidth, mHeight, flags, level + 1);
992                 drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1);
993             }
994             break;
995             case DrawLayer: {
996                 Layer* layer = (Layer*) getInt();
997                 float x = getFloat();
998                 float y = getFloat();
999                 SkPaint* paint = getPaint(renderer);
1000                 if (mCaching) {
1001                     paint->setAlpha(mMultipliedAlpha);
1002                 }
1003                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1004                         layer, x, y, paint);
1005                 drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
1006             }
1007             break;
1008             case DrawBitmap: {
1009                 SkBitmap* bitmap = getBitmap();
1010                 float x = getFloat();
1011                 float y = getFloat();
1012                 SkPaint* paint = getPaint(renderer);
1013                 if (mCaching) {
1014                     paint->setAlpha(mMultipliedAlpha);
1015                 }
1016                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1017                         bitmap, x, y, paint);
1018                 drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1019             }
1020             break;
1021             case DrawBitmapMatrix: {
1022                 SkBitmap* bitmap = getBitmap();
1023                 SkMatrix* matrix = getMatrix();
1024                 SkPaint* paint = getPaint(renderer);
1025                 DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
1026                         bitmap, matrix, paint);
1027                 drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
1028             }
1029             break;
1030             case DrawBitmapRect: {
1031                 SkBitmap* bitmap = getBitmap();
1032                 float f1 = getFloat();
1033                 float f2 = getFloat();
1034                 float f3 = getFloat();
1035                 float f4 = getFloat();
1036                 float f5 = getFloat();
1037                 float f6 = getFloat();
1038                 float f7 = getFloat();
1039                 float f8 = getFloat();
1040                 SkPaint* paint = getPaint(renderer);
1041                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1042                         (char*) indent, OP_NAMES[op], bitmap,
1043                         f1, f2, f3, f4, f5, f6, f7, f8,paint);
1044                 drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
1045             }
1046             break;
1047             case DrawBitmapData: {
1048                 SkBitmap* bitmap = getBitmapData();
1049                 float x = getFloat();
1050                 float y = getFloat();
1051                 SkPaint* paint = getPaint(renderer);
1052                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1053                         bitmap, x, y, paint);
1054                 drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
1055             }
1056             break;
1057             case DrawBitmapMesh: {
1058                 int32_t verticesCount = 0;
1059                 uint32_t colorsCount = 0;
1060 
1061                 SkBitmap* bitmap = getBitmap();
1062                 uint32_t meshWidth = getInt();
1063                 uint32_t meshHeight = getInt();
1064                 float* vertices = getFloats(verticesCount);
1065                 bool hasColors = getInt();
1066                 int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
1067                 SkPaint* paint = getPaint(renderer);
1068 
1069                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1070                 drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
1071                         colors, paint);
1072             }
1073             break;
1074             case DrawPatch: {
1075                 int32_t* xDivs = NULL;
1076                 int32_t* yDivs = NULL;
1077                 uint32_t* colors = NULL;
1078                 uint32_t xDivsCount = 0;
1079                 uint32_t yDivsCount = 0;
1080                 int8_t numColors = 0;
1081 
1082                 SkBitmap* bitmap = getBitmap();
1083 
1084                 xDivs = getInts(xDivsCount);
1085                 yDivs = getInts(yDivsCount);
1086                 colors = getUInts(numColors);
1087 
1088                 float left = getFloat();
1089                 float top = getFloat();
1090                 float right = getFloat();
1091                 float bottom = getFloat();
1092                 SkPaint* paint = getPaint(renderer);
1093 
1094                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1095                 drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
1096                         xDivsCount, yDivsCount, numColors, left, top, right, bottom, paint);
1097             }
1098             break;
1099             case DrawColor: {
1100                 int32_t color = getInt();
1101                 int32_t xferMode = getInt();
1102                 DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
1103                 drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
1104             }
1105             break;
1106             case DrawRect: {
1107                 float f1 = getFloat();
1108                 float f2 = getFloat();
1109                 float f3 = getFloat();
1110                 float f4 = getFloat();
1111                 SkPaint* paint = getPaint(renderer);
1112                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
1113                         f1, f2, f3, f4, paint);
1114                 drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
1115             }
1116             break;
1117             case DrawRoundRect: {
1118                 float f1 = getFloat();
1119                 float f2 = getFloat();
1120                 float f3 = getFloat();
1121                 float f4 = getFloat();
1122                 float f5 = getFloat();
1123                 float f6 = getFloat();
1124                 SkPaint* paint = getPaint(renderer);
1125                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
1126                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
1127                 drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
1128             }
1129             break;
1130             case DrawCircle: {
1131                 float f1 = getFloat();
1132                 float f2 = getFloat();
1133                 float f3 = getFloat();
1134                 SkPaint* paint = getPaint(renderer);
1135                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
1136                         (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
1137                 drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
1138             }
1139             break;
1140             case DrawOval: {
1141                 float f1 = getFloat();
1142                 float f2 = getFloat();
1143                 float f3 = getFloat();
1144                 float f4 = getFloat();
1145                 SkPaint* paint = getPaint(renderer);
1146                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
1147                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
1148                 drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
1149             }
1150             break;
1151             case DrawArc: {
1152                 float f1 = getFloat();
1153                 float f2 = getFloat();
1154                 float f3 = getFloat();
1155                 float f4 = getFloat();
1156                 float f5 = getFloat();
1157                 float f6 = getFloat();
1158                 int32_t i1 = getInt();
1159                 SkPaint* paint = getPaint(renderer);
1160                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
1161                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
1162                 drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
1163             }
1164             break;
1165             case DrawPath: {
1166                 SkPath* path = getPath();
1167                 SkPaint* paint = getPaint(renderer);
1168                 DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
1169                 drawGlStatus |= renderer.drawPath(path, paint);
1170             }
1171             break;
1172             case DrawLines: {
1173                 int32_t count = 0;
1174                 float* points = getFloats(count);
1175                 SkPaint* paint = getPaint(renderer);
1176                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1177                 drawGlStatus |= renderer.drawLines(points, count, paint);
1178             }
1179             break;
1180             case DrawPoints: {
1181                 int32_t count = 0;
1182                 float* points = getFloats(count);
1183                 SkPaint* paint = getPaint(renderer);
1184                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1185                 drawGlStatus |= renderer.drawPoints(points, count, paint);
1186             }
1187             break;
1188             case DrawText: {
1189                 getText(&text);
1190                 int32_t count = getInt();
1191                 float x = getFloat();
1192                 float y = getFloat();
1193                 SkPaint* paint = getPaint(renderer);
1194                 float length = getFloat();
1195                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
1196                         OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
1197                 drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y,
1198                         paint, length);
1199             }
1200             break;
1201             case DrawTextOnPath: {
1202                 getText(&text);
1203                 int32_t count = getInt();
1204                 SkPath* path = getPath();
1205                 float hOffset = getFloat();
1206                 float vOffset = getFloat();
1207                 SkPaint* paint = getPaint(renderer);
1208                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
1209                     text.text(), text.length(), count, paint);
1210                 drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
1211                         hOffset, vOffset, paint);
1212             }
1213             break;
1214             case DrawPosText: {
1215                 getText(&text);
1216                 int32_t count = getInt();
1217                 int32_t positionsCount = 0;
1218                 float* positions = getFloats(positionsCount);
1219                 SkPaint* paint = getPaint(renderer);
1220                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
1221                         OP_NAMES[op], text.text(), text.length(), count, paint);
1222                 drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
1223                         positions, paint);
1224             }
1225             break;
1226             case ResetShader: {
1227                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1228                 renderer.resetShader();
1229             }
1230             break;
1231             case SetupShader: {
1232                 SkiaShader* shader = getShader();
1233                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
1234                 renderer.setupShader(shader);
1235             }
1236             break;
1237             case ResetColorFilter: {
1238                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1239                 renderer.resetColorFilter();
1240             }
1241             break;
1242             case SetupColorFilter: {
1243                 SkiaColorFilter *colorFilter = getColorFilter();
1244                 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
1245                 renderer.setupColorFilter(colorFilter);
1246             }
1247             break;
1248             case ResetShadow: {
1249                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1250                 renderer.resetShadow();
1251             }
1252             break;
1253             case SetupShadow: {
1254                 float radius = getFloat();
1255                 float dx = getFloat();
1256                 float dy = getFloat();
1257                 int32_t color = getInt();
1258                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
1259                         radius, dx, dy, color);
1260                 renderer.setupShadow(radius, dx, dy, color);
1261             }
1262             break;
1263             case ResetPaintFilter: {
1264                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
1265                 renderer.resetPaintFilter();
1266             }
1267             break;
1268             case SetupPaintFilter: {
1269                 int32_t clearBits = getInt();
1270                 int32_t setBits = getInt();
1271                 DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
1272                         clearBits, setBits);
1273                 renderer.setupPaintFilter(clearBits, setBits);
1274             }
1275             break;
1276             default:
1277                 DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
1278                         (char*) indent, OP_NAMES[op]);
1279                 break;
1280         }
1281     }
1282 
1283     DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
1284     renderer.restoreToCount(restoreTo);
1285     renderer.endMark();
1286 
1287     DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
1288             drawGlStatus);
1289     return drawGlStatus;
1290 }
1291 
1292 ///////////////////////////////////////////////////////////////////////////////
1293 // Base structure
1294 ///////////////////////////////////////////////////////////////////////////////
1295 
DisplayListRenderer()1296 DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE),
1297         mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
1298 }
1299 
~DisplayListRenderer()1300 DisplayListRenderer::~DisplayListRenderer() {
1301     reset();
1302 }
1303 
reset()1304 void DisplayListRenderer::reset() {
1305     mWriter.reset();
1306 
1307     Caches& caches = Caches::getInstance();
1308     for (size_t i = 0; i < mBitmapResources.size(); i++) {
1309         caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
1310     }
1311     mBitmapResources.clear();
1312 
1313     for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
1314         SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
1315         caches.resourceCache.decrementRefcount(bitmap);
1316     }
1317     mOwnedBitmapResources.clear();
1318 
1319     for (size_t i = 0; i < mFilterResources.size(); i++) {
1320         caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
1321     }
1322     mFilterResources.clear();
1323 
1324     for (size_t i = 0; i < mShaders.size(); i++) {
1325         caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
1326     }
1327     mShaders.clear();
1328     mShaderMap.clear();
1329 
1330     for (size_t i = 0; i < mSourcePaths.size(); i++) {
1331         caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
1332     }
1333     mSourcePaths.clear();
1334 
1335     mPaints.clear();
1336     mPaintMap.clear();
1337 
1338     mPaths.clear();
1339     mPathMap.clear();
1340 
1341     mMatrices.clear();
1342 
1343     mHasDrawOps = false;
1344 }
1345 
1346 ///////////////////////////////////////////////////////////////////////////////
1347 // Operations
1348 ///////////////////////////////////////////////////////////////////////////////
1349 
getDisplayList(DisplayList * displayList)1350 DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
1351     if (!displayList) {
1352         displayList = new DisplayList(*this);
1353     } else {
1354         displayList->initFromDisplayListRenderer(*this, true);
1355     }
1356     displayList->setRenderable(mHasDrawOps);
1357     return displayList;
1358 }
1359 
isDeferred()1360 bool DisplayListRenderer::isDeferred() {
1361     return true;
1362 }
1363 
setViewport(int width,int height)1364 void DisplayListRenderer::setViewport(int width, int height) {
1365     mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
1366 
1367     mWidth = width;
1368     mHeight = height;
1369 }
1370 
prepareDirty(float left,float top,float right,float bottom,bool opaque)1371 int DisplayListRenderer::prepareDirty(float left, float top,
1372         float right, float bottom, bool opaque) {
1373     mSnapshot = new Snapshot(mFirstSnapshot,
1374             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
1375     mSaveCount = 1;
1376     mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
1377     mRestoreSaveCount = -1;
1378     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1379 }
1380 
finish()1381 void DisplayListRenderer::finish() {
1382     insertRestoreToCount();
1383     insertTranlate();
1384 }
1385 
interrupt()1386 void DisplayListRenderer::interrupt() {
1387 }
1388 
resume()1389 void DisplayListRenderer::resume() {
1390 }
1391 
callDrawGLFunction(Functor * functor,Rect & dirty)1392 status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
1393     // Ignore dirty during recording, it matters only when we replay
1394     addOp(DisplayList::DrawGLFunction);
1395     addInt((int) functor);
1396     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
1397 }
1398 
save(int flags)1399 int DisplayListRenderer::save(int flags) {
1400     addOp(DisplayList::Save);
1401     addInt(flags);
1402     return OpenGLRenderer::save(flags);
1403 }
1404 
restore()1405 void DisplayListRenderer::restore() {
1406     if (mRestoreSaveCount < 0) {
1407         restoreToCount(getSaveCount() - 1);
1408         return;
1409     }
1410 
1411     mRestoreSaveCount--;
1412     insertTranlate();
1413     OpenGLRenderer::restore();
1414 }
1415 
restoreToCount(int saveCount)1416 void DisplayListRenderer::restoreToCount(int saveCount) {
1417     mRestoreSaveCount = saveCount;
1418     insertTranlate();
1419     OpenGLRenderer::restoreToCount(saveCount);
1420 }
1421 
saveLayer(float left,float top,float right,float bottom,SkPaint * p,int flags)1422 int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
1423         SkPaint* p, int flags) {
1424     addOp(DisplayList::SaveLayer);
1425     addBounds(left, top, right, bottom);
1426     addPaint(p);
1427     addInt(flags);
1428     return OpenGLRenderer::save(flags);
1429 }
1430 
saveLayerAlpha(float left,float top,float right,float bottom,int alpha,int flags)1431 int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
1432         int alpha, int flags) {
1433     addOp(DisplayList::SaveLayerAlpha);
1434     addBounds(left, top, right, bottom);
1435     addInt(alpha);
1436     addInt(flags);
1437     return OpenGLRenderer::save(flags);
1438 }
1439 
translate(float dx,float dy)1440 void DisplayListRenderer::translate(float dx, float dy) {
1441     mHasTranslate = true;
1442     mTranslateX += dx;
1443     mTranslateY += dy;
1444     insertRestoreToCount();
1445     OpenGLRenderer::translate(dx, dy);
1446 }
1447 
rotate(float degrees)1448 void DisplayListRenderer::rotate(float degrees) {
1449     addOp(DisplayList::Rotate);
1450     addFloat(degrees);
1451     OpenGLRenderer::rotate(degrees);
1452 }
1453 
scale(float sx,float sy)1454 void DisplayListRenderer::scale(float sx, float sy) {
1455     addOp(DisplayList::Scale);
1456     addPoint(sx, sy);
1457     OpenGLRenderer::scale(sx, sy);
1458 }
1459 
skew(float sx,float sy)1460 void DisplayListRenderer::skew(float sx, float sy) {
1461     addOp(DisplayList::Skew);
1462     addPoint(sx, sy);
1463     OpenGLRenderer::skew(sx, sy);
1464 }
1465 
setMatrix(SkMatrix * matrix)1466 void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
1467     addOp(DisplayList::SetMatrix);
1468     addMatrix(matrix);
1469     OpenGLRenderer::setMatrix(matrix);
1470 }
1471 
concatMatrix(SkMatrix * matrix)1472 void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
1473     addOp(DisplayList::ConcatMatrix);
1474     addMatrix(matrix);
1475     OpenGLRenderer::concatMatrix(matrix);
1476 }
1477 
clipRect(float left,float top,float right,float bottom,SkRegion::Op op)1478 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1479         SkRegion::Op op) {
1480     addOp(DisplayList::ClipRect);
1481     addBounds(left, top, right, bottom);
1482     addInt(op);
1483     return OpenGLRenderer::clipRect(left, top, right, bottom, op);
1484 }
1485 
drawDisplayList(DisplayList * displayList,Rect & dirty,int32_t flags,uint32_t level)1486 status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
1487         Rect& dirty, int32_t flags, uint32_t level) {
1488     // dirty is an out parameter and should not be recorded,
1489     // it matters only when replaying the display list
1490 
1491     addOp(DisplayList::DrawDisplayList);
1492     addDisplayList(displayList);
1493     addInt(flags);
1494     return DrawGlInfo::kStatusDone;
1495 }
1496 
drawLayer(Layer * layer,float x,float y,SkPaint * paint)1497 status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
1498     addOp(DisplayList::DrawLayer);
1499     addInt((int) layer);
1500     addPoint(x, y);
1501     addPaint(paint);
1502     return DrawGlInfo::kStatusDone;
1503 }
1504 
drawBitmap(SkBitmap * bitmap,float left,float top,SkPaint * paint)1505 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
1506     const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
1507     uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
1508     addBitmap(bitmap);
1509     addPoint(left, top);
1510     addPaint(paint);
1511     addSkip(location);
1512     return DrawGlInfo::kStatusDone;
1513 }
1514 
drawBitmap(SkBitmap * bitmap,SkMatrix * matrix,SkPaint * paint)1515 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
1516     Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
1517     const mat4 transform(*matrix);
1518     transform.mapRect(r);
1519 
1520     const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
1521     uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
1522     addBitmap(bitmap);
1523     addMatrix(matrix);
1524     addPaint(paint);
1525     addSkip(location);
1526     return DrawGlInfo::kStatusDone;
1527 }
1528 
drawBitmap(SkBitmap * bitmap,float srcLeft,float srcTop,float srcRight,float srcBottom,float dstLeft,float dstTop,float dstRight,float dstBottom,SkPaint * paint)1529 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
1530         float srcRight, float srcBottom, float dstLeft, float dstTop,
1531         float dstRight, float dstBottom, SkPaint* paint) {
1532     const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
1533     uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
1534     addBitmap(bitmap);
1535     addBounds(srcLeft, srcTop, srcRight, srcBottom);
1536     addBounds(dstLeft, dstTop, dstRight, dstBottom);
1537     addPaint(paint);
1538     addSkip(location);
1539     return DrawGlInfo::kStatusDone;
1540 }
1541 
drawBitmapData(SkBitmap * bitmap,float left,float top,SkPaint * paint)1542 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
1543         SkPaint* paint) {
1544     const bool reject = quickReject(left, top, left + bitmap->width(), bitmap->height());
1545     uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
1546     addBitmapData(bitmap);
1547     addPoint(left, top);
1548     addPaint(paint);
1549     addSkip(location);
1550     return DrawGlInfo::kStatusDone;
1551 }
1552 
drawBitmapMesh(SkBitmap * bitmap,int meshWidth,int meshHeight,float * vertices,int * colors,SkPaint * paint)1553 status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
1554         float* vertices, int* colors, SkPaint* paint) {
1555     addOp(DisplayList::DrawBitmapMesh);
1556     addBitmap(bitmap);
1557     addInt(meshWidth);
1558     addInt(meshHeight);
1559     addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
1560     if (colors) {
1561         addInt(1);
1562         addInts(colors, (meshWidth + 1) * (meshHeight + 1));
1563     } else {
1564         addInt(0);
1565     }
1566     addPaint(paint);
1567     return DrawGlInfo::kStatusDone;
1568 }
1569 
drawPatch(SkBitmap * bitmap,const int32_t * xDivs,const int32_t * yDivs,const uint32_t * colors,uint32_t width,uint32_t height,int8_t numColors,float left,float top,float right,float bottom,SkPaint * paint)1570 status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
1571         const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
1572         int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
1573     const bool reject = quickReject(left, top, right, bottom);
1574     uint32_t* location = addOp(DisplayList::DrawPatch, reject);
1575     addBitmap(bitmap);
1576     addInts(xDivs, width);
1577     addInts(yDivs, height);
1578     addUInts(colors, numColors);
1579     addBounds(left, top, right, bottom);
1580     addPaint(paint);
1581     addSkip(location);
1582     return DrawGlInfo::kStatusDone;
1583 }
1584 
drawColor(int color,SkXfermode::Mode mode)1585 status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
1586     addOp(DisplayList::DrawColor);
1587     addInt(color);
1588     addInt(mode);
1589     return DrawGlInfo::kStatusDone;
1590 }
1591 
drawRect(float left,float top,float right,float bottom,SkPaint * paint)1592 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
1593         SkPaint* paint) {
1594     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1595             quickReject(left, top, right, bottom);
1596     uint32_t* location = addOp(DisplayList::DrawRect, reject);
1597     addBounds(left, top, right, bottom);
1598     addPaint(paint);
1599     addSkip(location);
1600     return DrawGlInfo::kStatusDone;
1601 }
1602 
drawRoundRect(float left,float top,float right,float bottom,float rx,float ry,SkPaint * paint)1603 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
1604         float rx, float ry, SkPaint* paint) {
1605     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
1606             quickReject(left, top, right, bottom);
1607     uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
1608     addBounds(left, top, right, bottom);
1609     addPoint(rx, ry);
1610     addPaint(paint);
1611     addSkip(location);
1612     return DrawGlInfo::kStatusDone;
1613 }
1614 
drawCircle(float x,float y,float radius,SkPaint * paint)1615 status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
1616     addOp(DisplayList::DrawCircle);
1617     addPoint(x, y);
1618     addFloat(radius);
1619     addPaint(paint);
1620     return DrawGlInfo::kStatusDone;
1621 }
1622 
drawOval(float left,float top,float right,float bottom,SkPaint * paint)1623 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
1624         SkPaint* paint) {
1625     addOp(DisplayList::DrawOval);
1626     addBounds(left, top, right, bottom);
1627     addPaint(paint);
1628     return DrawGlInfo::kStatusDone;
1629 }
1630 
drawArc(float left,float top,float right,float bottom,float startAngle,float sweepAngle,bool useCenter,SkPaint * paint)1631 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
1632         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1633     addOp(DisplayList::DrawArc);
1634     addBounds(left, top, right, bottom);
1635     addPoint(startAngle, sweepAngle);
1636     addInt(useCenter ? 1 : 0);
1637     addPaint(paint);
1638     return DrawGlInfo::kStatusDone;
1639 }
1640 
drawPath(SkPath * path,SkPaint * paint)1641 status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
1642     float left, top, offset;
1643     uint32_t width, height;
1644     computePathBounds(path, paint, left, top, offset, width, height);
1645 
1646     const bool reject = quickReject(left - offset, top - offset, width, height);
1647     uint32_t* location = addOp(DisplayList::DrawPath, reject);
1648     addPath(path);
1649     addPaint(paint);
1650     addSkip(location);
1651     return DrawGlInfo::kStatusDone;
1652 }
1653 
drawLines(float * points,int count,SkPaint * paint)1654 status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
1655     addOp(DisplayList::DrawLines);
1656     addFloats(points, count);
1657     addPaint(paint);
1658     return DrawGlInfo::kStatusDone;
1659 }
1660 
drawPoints(float * points,int count,SkPaint * paint)1661 status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
1662     addOp(DisplayList::DrawPoints);
1663     addFloats(points, count);
1664     addPaint(paint);
1665     return DrawGlInfo::kStatusDone;
1666 }
1667 
drawText(const char * text,int bytesCount,int count,float x,float y,SkPaint * paint,float length)1668 status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
1669         float x, float y, SkPaint* paint, float length) {
1670     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1671 
1672     // TODO: We should probably make a copy of the paint instead of modifying
1673     //       it; modifying the paint will change its generationID the first
1674     //       time, which might impact caches. More investigation needed to
1675     //       see if it matters.
1676     //       If we make a copy, then drawTextDecorations() should *not* make
1677     //       its own copy as it does right now.
1678     // Beware: this needs Glyph encoding (already done on the Paint constructor)
1679     paint->setAntiAlias(true);
1680     if (length < 0.0f) length = paint->measureText(text, bytesCount);
1681 
1682     bool reject = false;
1683     if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
1684         SkPaint::FontMetrics metrics;
1685         paint->getFontMetrics(&metrics, 0.0f);
1686         reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
1687     }
1688 
1689     uint32_t* location = addOp(DisplayList::DrawText, reject);
1690     addText(text, bytesCount);
1691     addInt(count);
1692     addPoint(x, y);
1693     addPaint(paint);
1694     addFloat(length);
1695     addSkip(location);
1696     return DrawGlInfo::kStatusDone;
1697 }
1698 
drawTextOnPath(const char * text,int bytesCount,int count,SkPath * path,float hOffset,float vOffset,SkPaint * paint)1699 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
1700         SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
1701     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1702     addOp(DisplayList::DrawTextOnPath);
1703     addText(text, bytesCount);
1704     addInt(count);
1705     addPath(path);
1706     addFloat(hOffset);
1707     addFloat(vOffset);
1708     paint->setAntiAlias(true);
1709     addPaint(paint);
1710     return DrawGlInfo::kStatusDone;
1711 }
1712 
drawPosText(const char * text,int bytesCount,int count,const float * positions,SkPaint * paint)1713 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
1714         const float* positions, SkPaint* paint) {
1715     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
1716     addOp(DisplayList::DrawPosText);
1717     addText(text, bytesCount);
1718     addInt(count);
1719     addFloats(positions, count * 2);
1720     paint->setAntiAlias(true);
1721     addPaint(paint);
1722     return DrawGlInfo::kStatusDone;
1723 }
1724 
resetShader()1725 void DisplayListRenderer::resetShader() {
1726     addOp(DisplayList::ResetShader);
1727 }
1728 
setupShader(SkiaShader * shader)1729 void DisplayListRenderer::setupShader(SkiaShader* shader) {
1730     addOp(DisplayList::SetupShader);
1731     addShader(shader);
1732 }
1733 
resetColorFilter()1734 void DisplayListRenderer::resetColorFilter() {
1735     addOp(DisplayList::ResetColorFilter);
1736 }
1737 
setupColorFilter(SkiaColorFilter * filter)1738 void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
1739     addOp(DisplayList::SetupColorFilter);
1740     addColorFilter(filter);
1741 }
1742 
resetShadow()1743 void DisplayListRenderer::resetShadow() {
1744     addOp(DisplayList::ResetShadow);
1745 }
1746 
setupShadow(float radius,float dx,float dy,int color)1747 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
1748     addOp(DisplayList::SetupShadow);
1749     addFloat(radius);
1750     addPoint(dx, dy);
1751     addInt(color);
1752 }
1753 
resetPaintFilter()1754 void DisplayListRenderer::resetPaintFilter() {
1755     addOp(DisplayList::ResetPaintFilter);
1756 }
1757 
setupPaintFilter(int clearBits,int setBits)1758 void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
1759     addOp(DisplayList::SetupPaintFilter);
1760     addInt(clearBits);
1761     addInt(setBits);
1762 }
1763 
1764 }; // namespace uirenderer
1765 }; // namespace android
1766