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