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