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