DisplayListRenderer.h revision ed6fcb034b44d9a6ac2fc72fee6030417811f234
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 DrawPoints, 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, Rect& dirty, 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 inline uint32_t getUInt() { 149 return mReader.readU32(); 150 } 151 152 SkMatrix* getMatrix() { 153 return (SkMatrix*) getInt(); 154 } 155 156 SkPath* getPath() { 157 return (SkPath*) getInt(); 158 } 159 160 SkPaint* getPaint() { 161 return (SkPaint*) getInt(); 162 } 163 164 DisplayList* getDisplayList() { 165 return (DisplayList*) getInt(); 166 } 167 168 inline float getFloat() { 169 return mReader.readScalar(); 170 } 171 172 int32_t* getInts(uint32_t& count) { 173 count = getInt(); 174 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 175 } 176 177 uint32_t* getUInts(int8_t& count) { 178 count = getInt(); 179 return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); 180 } 181 182 float* getFloats(int& count) { 183 count = getInt(); 184 return (float*) mReader.skip(count * sizeof(float)); 185 } 186 187 void getText(TextContainer* text) { 188 size_t length = text->mByteLength = getInt(); 189 text->mText = (const char*) mReader.skip(length); 190 } 191 192 Vector<SkBitmap*> mBitmapResources; 193 Vector<SkiaColorFilter*> mFilterResources; 194 195 Vector<SkPaint*> mPaints; 196 Vector<SkPath*> mPaths; 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 drawPoints(float* points, int count, SkPaint* paint); 269 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 270 271 void resetShader(); 272 void setupShader(SkiaShader* shader); 273 274 void resetColorFilter(); 275 void setupColorFilter(SkiaColorFilter* filter); 276 277 void resetShadow(); 278 void setupShadow(float radius, float dx, float dy, int color); 279 280 void reset(); 281 282 const SkWriter32& writeStream() const { 283 return mWriter; 284 } 285 286 const Vector<SkBitmap*>& getBitmapResources() const { 287 return mBitmapResources; 288 } 289 290 const Vector<SkiaShader*>& getShaders() const { 291 return mShaders; 292 } 293 294 const Vector<SkPaint*>& getPaints() const { 295 return mPaints; 296 } 297 298 const Vector<SkPath*>& getPaths() const { 299 return mPaths; 300 } 301 302 const Vector<SkMatrix*>& getMatrices() const { 303 return mMatrices; 304 } 305 306 const Vector<SkiaColorFilter*>& getFilterResources() const { 307 return mFilterResources; 308 } 309 310private: 311 void insertRestoreToCount() { 312 if (mRestoreSaveCount >= 0) { 313 mWriter.writeInt(DisplayList::RestoreToCount); 314 addInt(mRestoreSaveCount); 315 mRestoreSaveCount = -1; 316 } 317 } 318 319 inline void addOp(DisplayList::Op drawOp) { 320 insertRestoreToCount(); 321 mWriter.writeInt(drawOp); 322 } 323 324 inline void addInt(int value) { 325 mWriter.writeInt(value); 326 } 327 328 inline void addSize(uint32_t w, uint32_t h) { 329 mWriter.writeInt(w); 330 mWriter.writeInt(h); 331 } 332 333 void addInts(const int32_t* values, uint32_t count) { 334 mWriter.writeInt(count); 335 for (uint32_t i = 0; i < count; i++) { 336 mWriter.writeInt(values[i]); 337 } 338 } 339 340 void addUInts(const uint32_t* values, int8_t count) { 341 mWriter.writeInt(count); 342 for (int8_t i = 0; i < count; i++) { 343 mWriter.writeInt(values[i]); 344 } 345 } 346 347 inline void addFloat(float value) { 348 mWriter.writeScalar(value); 349 } 350 351 void addFloats(const float* values, int count) { 352 mWriter.writeInt(count); 353 for (int i = 0; i < count; i++) { 354 mWriter.writeScalar(values[i]); 355 } 356 } 357 358 inline void addPoint(float x, float y) { 359 mWriter.writeScalar(x); 360 mWriter.writeScalar(y); 361 } 362 363 inline void addBounds(float left, float top, float right, float bottom) { 364 mWriter.writeScalar(left); 365 mWriter.writeScalar(top); 366 mWriter.writeScalar(right); 367 mWriter.writeScalar(bottom); 368 } 369 370 inline void addText(const void* text, size_t byteLength) { 371 mWriter.writeInt(byteLength); 372 mWriter.writePad(text, byteLength); 373 } 374 375 inline void addPath(SkPath* path) { 376 if (!path) { 377 addInt((int) NULL); 378 return; 379 } 380 381 SkPath* pathCopy = mPathMap.valueFor(path); 382 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 383 pathCopy = new SkPath(*path); 384 mPathMap.add(path, pathCopy); 385 mPaths.add(pathCopy); 386 } 387 388 addInt((int) pathCopy); 389 } 390 391 inline void addPaint(SkPaint* paint) { 392 if (!paint) { 393 addInt((int) NULL); 394 return; 395 } 396 397 SkPaint* paintCopy = mPaintMap.valueFor(paint); 398 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 399 paintCopy = new SkPaint(*paint); 400 mPaintMap.add(paint, paintCopy); 401 mPaints.add(paintCopy); 402 } 403 404 addInt((int) paintCopy); 405 } 406 407 inline void addDisplayList(DisplayList* displayList) { 408 // TODO: To be safe, the display list should be ref-counted in the 409 // resources cache, but we rely on the caller (UI toolkit) to 410 // do the right thing for now 411 addInt((int) displayList); 412 } 413 414 inline void addMatrix(SkMatrix* matrix) { 415 // Copying the matrix is cheap and prevents against the user changing the original 416 // matrix before the operation that uses it 417 addInt((int) new SkMatrix(*matrix)); 418 } 419 420 inline void addBitmap(SkBitmap* bitmap) { 421 // Note that this assumes the bitmap is immutable. There are cases this won't handle 422 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 423 // contents, and drawing again. The only fix would be to always copy it the first time, 424 // which doesn't seem worth the extra cycles for this unlikely case. 425 addInt((int) bitmap); 426 mBitmapResources.add(bitmap); 427 Caches& caches = Caches::getInstance(); 428 caches.resourceCache.incrementRefcount(bitmap); 429 } 430 431 inline void addShader(SkiaShader* shader) { 432 if (!shader) { 433 addInt((int) NULL); 434 return; 435 } 436 437 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 438 // TODO: We also need to handle generation ID changes in compose shaders 439 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 440 shaderCopy = shader->copy(); 441 mShaderMap.add(shader, shaderCopy); 442 mShaders.add(shaderCopy); 443 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 444 } 445 446 addInt((int) shaderCopy); 447 } 448 449 inline void addColorFilter(SkiaColorFilter* colorFilter) { 450 addInt((int) colorFilter); 451 mFilterResources.add(colorFilter); 452 Caches& caches = Caches::getInstance(); 453 caches.resourceCache.incrementRefcount(colorFilter); 454 } 455 456 Vector<SkBitmap*> mBitmapResources; 457 Vector<SkiaColorFilter*> mFilterResources; 458 459 Vector<SkPaint*> mPaints; 460 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 461 462 Vector<SkPath*> mPaths; 463 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 464 465 Vector<SkiaShader*> mShaders; 466 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 467 468 Vector<SkMatrix*> mMatrices; 469 470 SkWriter32 mWriter; 471 472 DisplayList *mDisplayList; 473 474 int mRestoreSaveCount; 475 476 friend class DisplayList; 477 478}; // class DisplayListRenderer 479 480}; // namespace uirenderer 481}; // namespace android 482 483#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 484