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