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