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