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