DisplayListRenderer.h revision 8b2f5267f16c295f12faab810527cd6311997e34
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 32namespace android { 33namespace uirenderer { 34 35/////////////////////////////////////////////////////////////////////////////// 36// Defines 37/////////////////////////////////////////////////////////////////////////////// 38 39#define MIN_WRITER_SIZE 16384 40#define HEAP_BLOCK_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// Helpers 51/////////////////////////////////////////////////////////////////////////////// 52 53class PathHeap: public SkRefCnt { 54public: 55 PathHeap(); 56 PathHeap(SkFlattenableReadBuffer& buffer); 57 ~PathHeap(); 58 59 int append(const SkPath& path); 60 61 int count() const { return mPaths.count(); } 62 63 SkPath& operator[](int index) const { 64 return *mPaths[index]; 65 } 66 67 void flatten(SkFlattenableWriteBuffer& buffer) const; 68 69private: 70 SkChunkAlloc mHeap; 71 SkTDArray<SkPath*> mPaths; 72}; 73 74/////////////////////////////////////////////////////////////////////////////// 75// Display list 76/////////////////////////////////////////////////////////////////////////////// 77 78class DisplayListRenderer; 79 80/** 81 * Replays recorded drawing commands. 82 */ 83class DisplayList { 84public: 85 DisplayList(const DisplayListRenderer& recorder); 86 ~DisplayList(); 87 88 // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file 89 // when modifying this file 90 enum Op { 91 AcquireContext = 0, 92 ReleaseContext, 93 Save, 94 Restore, 95 RestoreToCount, 96 SaveLayer, 97 SaveLayerAlpha, 98 Translate, 99 Rotate, 100 Scale, 101 Skew, 102 SetMatrix, 103 ConcatMatrix, 104 ClipRect, 105 DrawDisplayList, 106 DrawLayer, 107 DrawBitmap, 108 DrawBitmapMatrix, 109 DrawBitmapRect, 110 DrawBitmapMesh, 111 DrawPatch, 112 DrawColor, 113 DrawRect, 114 DrawRoundRect, 115 DrawCircle, 116 DrawOval, 117 DrawArc, 118 DrawPath, 119 DrawLines, 120 DrawText, 121 ResetShader, 122 SetupShader, 123 ResetColorFilter, 124 SetupColorFilter, 125 ResetShadow, 126 SetupShadow, 127 }; 128 129 static const char* OP_NAMES[]; 130 131 void initFromDisplayListRenderer(const DisplayListRenderer& recorder); 132 133 void 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 prepare(bool opaque); 243 void finish(); 244 245 void acquireContext(); 246 void releaseContext(); 247 248 int save(int flags); 249 void restore(); 250 void restoreToCount(int saveCount); 251 252 int saveLayer(float left, float top, float right, float bottom, 253 SkPaint* p, int flags); 254 int saveLayerAlpha(float left, float top, float right, float bottom, 255 int alpha, int flags); 256 257 void translate(float dx, float dy); 258 void rotate(float degrees); 259 void scale(float sx, float sy); 260 void skew(float sx, float sy); 261 262 void setMatrix(SkMatrix* matrix); 263 void concatMatrix(SkMatrix* matrix); 264 265 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 266 267 void drawDisplayList(DisplayList* displayList, 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 drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 290 291 void resetShader(); 292 void setupShader(SkiaShader* shader); 293 294 void resetColorFilter(); 295 void setupColorFilter(SkiaColorFilter* filter); 296 297 void resetShadow(); 298 void setupShadow(float radius, float dx, float dy, int color); 299 300 void reset(); 301 302 const SkWriter32& writeStream() const { 303 return mWriter; 304 } 305 306 const Vector<SkBitmap*>& getBitmapResources() const { 307 return mBitmapResources; 308 } 309 310 const Vector<SkiaShader*>& getShaders() const { 311 return mShaders; 312 } 313 314 const Vector<SkPaint*>& getPaints() const { 315 return mPaints; 316 } 317 318 const Vector<SkMatrix*>& getMatrices() const { 319 return mMatrices; 320 } 321 322 const Vector<SkiaColorFilter*>& getFilterResources() const { 323 return mFilterResources; 324 } 325 326private: 327 void insertRestoreToCount() { 328 if (mRestoreSaveCount >= 0) { 329 mWriter.writeInt(DisplayList::RestoreToCount); 330 addInt(mRestoreSaveCount); 331 mRestoreSaveCount = -1; 332 } 333 } 334 335 inline void addOp(DisplayList::Op drawOp) { 336 insertRestoreToCount(); 337 mWriter.writeInt(drawOp); 338 } 339 340 inline void addInt(int value) { 341 mWriter.writeInt(value); 342 } 343 344 void addInts(const int32_t* values, uint32_t count) { 345 mWriter.writeInt(count); 346 for (uint32_t i = 0; i < count; i++) { 347 mWriter.writeInt(values[i]); 348 } 349 } 350 351 void addUInts(const uint32_t* values, int8_t count) { 352 mWriter.writeInt(count); 353 for (int8_t i = 0; i < count; i++) { 354 mWriter.writeInt(values[i]); 355 } 356 } 357 358 inline void addFloat(float value) { 359 mWriter.writeScalar(value); 360 } 361 362 void addFloats(const float* values, int count) { 363 mWriter.writeInt(count); 364 for (int i = 0; i < count; i++) { 365 mWriter.writeScalar(values[i]); 366 } 367 } 368 369 inline void addPoint(float x, float y) { 370 mWriter.writeScalar(x); 371 mWriter.writeScalar(y); 372 } 373 374 inline void addBounds(float left, float top, float right, float bottom) { 375 mWriter.writeScalar(left); 376 mWriter.writeScalar(top); 377 mWriter.writeScalar(right); 378 mWriter.writeScalar(bottom); 379 } 380 381 inline void addText(const void* text, size_t byteLength) { 382 mWriter.writeInt(byteLength); 383 mWriter.writePad(text, byteLength); 384 } 385 386 inline void addPath(const SkPath* path) { 387 if (mPathHeap == NULL) { 388 mPathHeap = new PathHeap(); 389 } 390 addInt(mPathHeap->append(*path)); 391 } 392 393 inline void addPaint(SkPaint* paint) { 394 if (!paint) { 395 addInt((int) NULL); 396 return; 397 } 398 399 SkPaint* paintCopy = mPaintMap.valueFor(paint); 400 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 401 paintCopy = new SkPaint(*paint); 402 mPaintMap.add(paint, paintCopy); 403 mPaints.add(paintCopy); 404 } 405 406 addInt((int) paintCopy); 407 } 408 409 inline void addDisplayList(DisplayList* displayList) { 410 // TODO: To be safe, the display list should be ref-counted in the 411 // resources cache, but we rely on the caller (UI toolkit) to 412 // do the right thing for now 413 addInt((int) displayList); 414 } 415 416 inline void addMatrix(SkMatrix* matrix) { 417 // Copying the matrix is cheap and prevents against the user changing the original 418 // matrix before the operation that uses it 419 addInt((int) new SkMatrix(*matrix)); 420 } 421 422 inline void addBitmap(SkBitmap* bitmap) { 423 // Note that this assumes the bitmap is immutable. There are cases this won't handle 424 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 425 // contents, and drawing again. The only fix would be to always copy it the first time, 426 // which doesn't seem worth the extra cycles for this unlikely case. 427 addInt((int) bitmap); 428 mBitmapResources.add(bitmap); 429 Caches& caches = Caches::getInstance(); 430 caches.resourceCache.incrementRefcount(bitmap); 431 } 432 433 inline void addShader(SkiaShader* shader) { 434 if (!shader) { 435 addInt((int) NULL); 436 return; 437 } 438 439 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 440 // TODO: We also need to handle generation ID changes in compose shaders 441 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 442 shaderCopy = shader->copy(); 443 mShaderMap.add(shader, shaderCopy); 444 mShaders.add(shaderCopy); 445 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 446 } 447 448 addInt((int) shaderCopy); 449 } 450 451 inline void addColorFilter(SkiaColorFilter* colorFilter) { 452 addInt((int) colorFilter); 453 mFilterResources.add(colorFilter); 454 Caches& caches = Caches::getInstance(); 455 caches.resourceCache.incrementRefcount(colorFilter); 456 } 457 458 SkChunkAlloc mHeap; 459 460 Vector<SkBitmap*> mBitmapResources; 461 Vector<SkiaColorFilter*> mFilterResources; 462 463 Vector<SkPaint*> mPaints; 464 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 465 466 Vector<SkiaShader*> mShaders; 467 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 468 469 Vector<SkMatrix*> mMatrices; 470 471 PathHeap* mPathHeap; 472 SkWriter32 mWriter; 473 474 SkRefCntRecorder mRCRecorder; 475 SkRefCntRecorder mTFRecorder; 476 477 DisplayList *mDisplayList; 478 479 int mRestoreSaveCount; 480 481 friend class DisplayList; 482 483}; // class DisplayListRenderer 484 485}; // namespace uirenderer 486}; // namespace android 487 488#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 489