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