DisplayListRenderer.h revision 5a7e828842c26f64bb6e0ef3e0019e1949b245ee
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#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 18#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 19 20#include <SkChunkAlloc.h> 21#include <SkFlattenable.h> 22#include <SkMatrix.h> 23#include <SkPaint.h> 24#include <SkPath.h> 25#include <SkPictureFlat.h> 26#include <SkRefCnt.h> 27#include <SkTDArray.h> 28#include <SkTSearch.h> 29 30#include "OpenGLRenderer.h" 31#include "utils/Functor.h" 32 33namespace android { 34namespace uirenderer { 35 36/////////////////////////////////////////////////////////////////////////////// 37// Defines 38/////////////////////////////////////////////////////////////////////////////// 39 40#define MIN_WRITER_SIZE 16384 41 42// Debug 43#if DEBUG_DISPLAY_LIST 44 #define DISPLAY_LIST_LOGD(...) LOGD(__VA_ARGS__) 45#else 46 #define DISPLAY_LIST_LOGD(...) 47#endif 48 49/////////////////////////////////////////////////////////////////////////////// 50// Display list 51/////////////////////////////////////////////////////////////////////////////// 52 53class DisplayListRenderer; 54 55/** 56 * Replays recorded drawing commands. 57 */ 58class DisplayList { 59public: 60 DisplayList(const DisplayListRenderer& recorder); 61 ~DisplayList(); 62 63 // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file 64 // when modifying this file 65 enum Op { 66 Save = 0, 67 Restore, 68 RestoreToCount, 69 SaveLayer, 70 SaveLayerAlpha, 71 Translate, 72 Rotate, 73 Scale, 74 Skew, 75 SetMatrix, 76 ConcatMatrix, 77 ClipRect, 78 DrawDisplayList, 79 DrawLayer, 80 DrawBitmap, 81 DrawBitmapMatrix, 82 DrawBitmapRect, 83 DrawBitmapMesh, 84 DrawPatch, 85 DrawColor, 86 DrawRect, 87 DrawRoundRect, 88 DrawCircle, 89 DrawOval, 90 DrawArc, 91 DrawPath, 92 DrawLines, 93 DrawText, 94 ResetShader, 95 SetupShader, 96 ResetColorFilter, 97 SetupColorFilter, 98 ResetShadow, 99 SetupShadow, 100 DrawGLFunction, 101 }; 102 103 static const char* OP_NAMES[]; 104 105 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); 106 107 bool replay(OpenGLRenderer& renderer, uint32_t level = 0); 108 109private: 110 void init(); 111 112 void clearResources(); 113 114 class TextContainer { 115 public: 116 size_t length() const { 117 return mByteLength; 118 } 119 120 const char* text() const { 121 return (const char*) mText; 122 } 123 124 size_t mByteLength; 125 const char* mText; 126 }; 127 128 SkBitmap* getBitmap() { 129 return (SkBitmap*) getInt(); 130 } 131 132 SkiaShader* getShader() { 133 return (SkiaShader*) getInt(); 134 } 135 136 SkiaColorFilter* getColorFilter() { 137 return (SkiaColorFilter*) getInt(); 138 } 139 140 inline int getIndex() { 141 return mReader.readInt(); 142 } 143 144 inline int getInt() { 145 return mReader.readInt(); 146 } 147 148 SkMatrix* getMatrix() { 149 return (SkMatrix*) getInt(); 150 } 151 152 SkPath* getPath() { 153 return (SkPath*) getInt(); 154 } 155 156 SkPaint* getPaint() { 157 return (SkPaint*) getInt(); 158 } 159 160 DisplayList* getDisplayList() { 161 return (DisplayList*) getInt(); 162 } 163 164 inline float getFloat() { 165 return mReader.readScalar(); 166 } 167 168 int32_t* getInts(uint32_t& count) { 169 count = getInt(); 170 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 171 } 172 173 uint32_t* getUInts(int8_t& count) { 174 count = getInt(); 175 return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); 176 } 177 178 float* getFloats(int& count) { 179 count = getInt(); 180 return (float*) mReader.skip(count * sizeof(float)); 181 } 182 183 void getText(TextContainer* text) { 184 size_t length = text->mByteLength = getInt(); 185 text->mText = (const char*) mReader.skip(length); 186 } 187 188 Vector<SkBitmap*> mBitmapResources; 189 Vector<SkiaColorFilter*> mFilterResources; 190 191 Vector<SkPaint*> mPaints; 192 Vector<SkPath*> mPaths; 193 Vector<SkPath*> mOriginalPaths; 194 Vector<SkMatrix*> mMatrices; 195 Vector<SkiaShader*> mShaders; 196 197 mutable SkFlattenableReadBuffer mReader; 198}; 199 200/////////////////////////////////////////////////////////////////////////////// 201// Renderer 202/////////////////////////////////////////////////////////////////////////////// 203 204/** 205 * Records drawing commands in a display list for latter playback. 206 */ 207class DisplayListRenderer: public OpenGLRenderer { 208public: 209 DisplayListRenderer(); 210 ~DisplayListRenderer(); 211 212 DisplayList* getDisplayList(); 213 214 void setViewport(int width, int height); 215 void prepareDirty(float left, float top, float right, float bottom, bool opaque); 216 void finish(); 217 218 bool callDrawGLFunction(Functor *functor); 219 220 void interrupt(); 221 void resume(); 222 223 int save(int flags); 224 void restore(); 225 void restoreToCount(int saveCount); 226 227 int saveLayer(float left, float top, float right, float bottom, 228 SkPaint* p, int flags); 229 int saveLayerAlpha(float left, float top, float right, float bottom, 230 int alpha, int flags); 231 232 void translate(float dx, float dy); 233 void rotate(float degrees); 234 void scale(float sx, float sy); 235 void skew(float sx, float sy); 236 237 void setMatrix(SkMatrix* matrix); 238 void concatMatrix(SkMatrix* matrix); 239 240 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 241 242 bool drawDisplayList(DisplayList* displayList, uint32_t level = 0); 243 void drawLayer(Layer* layer, float x, float y, SkPaint* paint); 244 void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 245 void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 246 void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 247 float srcRight, float srcBottom, float dstLeft, float dstTop, 248 float dstRight, float dstBottom, SkPaint* paint); 249 void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 250 float* vertices, int* colors, SkPaint* paint); 251 void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 252 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 253 float left, float top, float right, float bottom, SkPaint* paint); 254 void drawColor(int color, SkXfermode::Mode mode); 255 void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 256 void drawRoundRect(float left, float top, float right, float bottom, 257 float rx, float ry, SkPaint* paint); 258 void drawCircle(float x, float y, float radius, SkPaint* paint); 259 void drawOval(float left, float top, float right, float bottom, SkPaint* paint); 260 void drawArc(float left, float top, float right, float bottom, 261 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); 262 void drawPath(SkPath* path, SkPaint* paint); 263 void drawLines(float* points, int count, SkPaint* paint); 264 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 265 266 void resetShader(); 267 void setupShader(SkiaShader* shader); 268 269 void resetColorFilter(); 270 void setupColorFilter(SkiaColorFilter* filter); 271 272 void resetShadow(); 273 void setupShadow(float radius, float dx, float dy, int color); 274 275 void reset(); 276 277 const SkWriter32& writeStream() const { 278 return mWriter; 279 } 280 281 const Vector<SkBitmap*>& getBitmapResources() const { 282 return mBitmapResources; 283 } 284 285 const Vector<SkiaShader*>& getShaders() const { 286 return mShaders; 287 } 288 289 const Vector<SkPaint*>& getPaints() const { 290 return mPaints; 291 } 292 293 const Vector<SkPath*>& getPaths() const { 294 return mPaths; 295 } 296 297 const Vector<SkPath*>& getOriginalPaths() const { 298 return mOriginalPaths; 299 } 300 301 const Vector<SkMatrix*>& getMatrices() const { 302 return mMatrices; 303 } 304 305 const Vector<SkiaColorFilter*>& getFilterResources() const { 306 return mFilterResources; 307 } 308 309private: 310 void insertRestoreToCount() { 311 if (mRestoreSaveCount >= 0) { 312 mWriter.writeInt(DisplayList::RestoreToCount); 313 addInt(mRestoreSaveCount); 314 mRestoreSaveCount = -1; 315 } 316 } 317 318 inline void addOp(DisplayList::Op drawOp) { 319 insertRestoreToCount(); 320 mWriter.writeInt(drawOp); 321 } 322 323 inline void addInt(int value) { 324 mWriter.writeInt(value); 325 } 326 327 void addInts(const int32_t* values, uint32_t count) { 328 mWriter.writeInt(count); 329 for (uint32_t i = 0; i < count; i++) { 330 mWriter.writeInt(values[i]); 331 } 332 } 333 334 void addUInts(const uint32_t* values, int8_t count) { 335 mWriter.writeInt(count); 336 for (int8_t i = 0; i < count; i++) { 337 mWriter.writeInt(values[i]); 338 } 339 } 340 341 inline void addFloat(float value) { 342 mWriter.writeScalar(value); 343 } 344 345 void addFloats(const float* values, int count) { 346 mWriter.writeInt(count); 347 for (int i = 0; i < count; i++) { 348 mWriter.writeScalar(values[i]); 349 } 350 } 351 352 inline void addPoint(float x, float y) { 353 mWriter.writeScalar(x); 354 mWriter.writeScalar(y); 355 } 356 357 inline void addBounds(float left, float top, float right, float bottom) { 358 mWriter.writeScalar(left); 359 mWriter.writeScalar(top); 360 mWriter.writeScalar(right); 361 mWriter.writeScalar(bottom); 362 } 363 364 inline void addText(const void* text, size_t byteLength) { 365 mWriter.writeInt(byteLength); 366 mWriter.writePad(text, byteLength); 367 } 368 369 inline void addPath(SkPath* path) { 370 if (!path) { 371 addInt((int) NULL); 372 return; 373 } 374 375 SkPath* pathCopy = mPathMap.valueFor(path); 376 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 377 if (pathCopy == NULL) { 378 pathCopy = path; 379 mOriginalPaths.add(path); 380 Caches& caches = Caches::getInstance(); 381 caches.resourceCache.incrementRefcount(path); 382 } else { 383 pathCopy = new SkPath(*path); 384 mPaths.add(pathCopy); 385 } 386 mPathMap.add(path, pathCopy); 387 } 388 389 addInt((int) pathCopy); 390 } 391 392 inline void addPaint(SkPaint* paint) { 393 if (!paint) { 394 addInt((int) NULL); 395 return; 396 } 397 398 SkPaint* paintCopy = mPaintMap.valueFor(paint); 399 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 400 paintCopy = new SkPaint(*paint); 401 mPaintMap.add(paint, paintCopy); 402 mPaints.add(paintCopy); 403 } 404 405 addInt((int) paintCopy); 406 } 407 408 inline void addDisplayList(DisplayList* displayList) { 409 // TODO: To be safe, the display list should be ref-counted in the 410 // resources cache, but we rely on the caller (UI toolkit) to 411 // do the right thing for now 412 addInt((int) displayList); 413 } 414 415 inline void addMatrix(SkMatrix* matrix) { 416 // Copying the matrix is cheap and prevents against the user changing the original 417 // matrix before the operation that uses it 418 addInt((int) new SkMatrix(*matrix)); 419 } 420 421 inline void addBitmap(SkBitmap* bitmap) { 422 // Note that this assumes the bitmap is immutable. There are cases this won't handle 423 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 424 // contents, and drawing again. The only fix would be to always copy it the first time, 425 // which doesn't seem worth the extra cycles for this unlikely case. 426 addInt((int) bitmap); 427 mBitmapResources.add(bitmap); 428 Caches& caches = Caches::getInstance(); 429 caches.resourceCache.incrementRefcount(bitmap); 430 } 431 432 inline void addShader(SkiaShader* shader) { 433 if (!shader) { 434 addInt((int) NULL); 435 return; 436 } 437 438 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 439 // TODO: We also need to handle generation ID changes in compose shaders 440 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 441 shaderCopy = shader->copy(); 442 mShaderMap.add(shader, shaderCopy); 443 mShaders.add(shaderCopy); 444 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 445 } 446 447 addInt((int) shaderCopy); 448 } 449 450 inline void addColorFilter(SkiaColorFilter* colorFilter) { 451 addInt((int) colorFilter); 452 mFilterResources.add(colorFilter); 453 Caches& caches = Caches::getInstance(); 454 caches.resourceCache.incrementRefcount(colorFilter); 455 } 456 457 Vector<SkBitmap*> mBitmapResources; 458 Vector<SkiaColorFilter*> mFilterResources; 459 460 Vector<SkPaint*> mPaints; 461 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 462 463 Vector<SkPath*> mOriginalPaths; 464 Vector<SkPath*> mPaths; 465 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 466 467 Vector<SkiaShader*> mShaders; 468 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 469 470 Vector<SkMatrix*> mMatrices; 471 472 SkWriter32 mWriter; 473 474 DisplayList *mDisplayList; 475 476 int mRestoreSaveCount; 477 478 friend class DisplayList; 479 480}; // class DisplayListRenderer 481 482}; // namespace uirenderer 483}; // namespace android 484 485#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 486