DisplayListRenderer.h revision ad1daaa87b793af30f3dd67a0f3cd5c0fd6ac0c1
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(0xdeaddead); 395 uint32_t* location = reject ? 396 mWriter.peek32(mWriter.size() - sizeof(int32_t)) : NULL; 397 return location; 398 } 399 mWriter.writeInt(drawOp); 400 return NULL; 401 } 402 403 inline void addSkip(uint32_t* location) { 404 if (location) { 405 *location = (int32_t) (mWriter.peek32( 406 mWriter.size() - sizeof(int32_t)) - location); 407 } 408 } 409 410 inline void addInt(int32_t value) { 411 mWriter.writeInt(value); 412 } 413 414 inline void addSize(uint32_t w, uint32_t h) { 415 mWriter.writeInt(w); 416 mWriter.writeInt(h); 417 } 418 419 void addInts(const int32_t* values, uint32_t count) { 420 mWriter.writeInt(count); 421 for (uint32_t i = 0; i < count; i++) { 422 mWriter.writeInt(values[i]); 423 } 424 } 425 426 void addUInts(const uint32_t* values, int8_t count) { 427 mWriter.writeInt(count); 428 for (int8_t i = 0; i < count; i++) { 429 mWriter.writeInt(values[i]); 430 } 431 } 432 433 inline void addFloat(float value) { 434 mWriter.writeScalar(value); 435 } 436 437 void addFloats(const float* values, int32_t count) { 438 mWriter.writeInt(count); 439 for (int32_t i = 0; i < count; i++) { 440 mWriter.writeScalar(values[i]); 441 } 442 } 443 444 inline void addPoint(float x, float y) { 445 mWriter.writeScalar(x); 446 mWriter.writeScalar(y); 447 } 448 449 inline void addBounds(float left, float top, float right, float bottom) { 450 mWriter.writeScalar(left); 451 mWriter.writeScalar(top); 452 mWriter.writeScalar(right); 453 mWriter.writeScalar(bottom); 454 } 455 456 inline void addText(const void* text, size_t byteLength) { 457 mWriter.writeInt(byteLength); 458 mWriter.writePad(text, byteLength); 459 } 460 461 inline void addPath(SkPath* path) { 462 if (!path) { 463 addInt((int) NULL); 464 return; 465 } 466 467 SkPath* pathCopy = mPathMap.valueFor(path); 468 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 469 pathCopy = new SkPath(*path); 470 pathCopy->setSourcePath(path); 471 // replaceValueFor() performs an add if the entry doesn't exist 472 mPathMap.replaceValueFor(path, pathCopy); 473 mPaths.add(pathCopy); 474 } 475 476 addInt((int) pathCopy); 477 } 478 479 inline void addPaint(SkPaint* paint) { 480 if (!paint) { 481 addInt((int) NULL); 482 return; 483 } 484 485 SkPaint* paintCopy = mPaintMap.valueFor(paint); 486 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 487 paintCopy = new SkPaint(*paint); 488 // replaceValueFor() performs an add if the entry doesn't exist 489 mPaintMap.replaceValueFor(paint, paintCopy); 490 mPaints.add(paintCopy); 491 } 492 493 addInt((int) paintCopy); 494 } 495 496 inline void addDisplayList(DisplayList* displayList) { 497 // TODO: To be safe, the display list should be ref-counted in the 498 // resources cache, but we rely on the caller (UI toolkit) to 499 // do the right thing for now 500 addInt((int) displayList); 501 } 502 503 inline void addMatrix(SkMatrix* matrix) { 504 // Copying the matrix is cheap and prevents against the user changing the original 505 // matrix before the operation that uses it 506 SkMatrix* copy = new SkMatrix(*matrix); 507 addInt((int) copy); 508 mMatrices.add(copy); 509 } 510 511 inline void addBitmap(SkBitmap* bitmap) { 512 // Note that this assumes the bitmap is immutable. There are cases this won't handle 513 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 514 // contents, and drawing again. The only fix would be to always copy it the first time, 515 // which doesn't seem worth the extra cycles for this unlikely case. 516 addInt((int) bitmap); 517 mBitmapResources.add(bitmap); 518 Caches::getInstance().resourceCache.incrementRefcount(bitmap); 519 } 520 521 inline void addShader(SkiaShader* shader) { 522 if (!shader) { 523 addInt((int) NULL); 524 return; 525 } 526 527 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 528 // TODO: We also need to handle generation ID changes in compose shaders 529 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 530 shaderCopy = shader->copy(); 531 // replaceValueFor() performs an add if the entry doesn't exist 532 mShaderMap.replaceValueFor(shader, shaderCopy); 533 mShaders.add(shaderCopy); 534 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 535 } 536 537 addInt((int) shaderCopy); 538 } 539 540 inline void addColorFilter(SkiaColorFilter* colorFilter) { 541 addInt((int) colorFilter); 542 mFilterResources.add(colorFilter); 543 Caches::getInstance().resourceCache.incrementRefcount(colorFilter); 544 } 545 546 Vector<SkBitmap*> mBitmapResources; 547 Vector<SkiaColorFilter*> mFilterResources; 548 549 Vector<SkPaint*> mPaints; 550 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 551 552 Vector<SkPath*> mPaths; 553 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 554 555 Vector<SkiaShader*> mShaders; 556 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 557 558 Vector<SkMatrix*> mMatrices; 559 560 SkWriter32 mWriter; 561 562 int mRestoreSaveCount; 563 564 float mTranslateX; 565 float mTranslateY; 566 bool mHasTranslate; 567 568 bool mHasDrawOps; 569 570 friend class DisplayList; 571 572}; // class DisplayListRenderer 573 574}; // namespace uirenderer 575}; // namespace android 576 577#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 578