DisplayListRenderer.h revision 5a7b466a2b4b7ced739bd5c31e022de61650545a
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 242 void acquireContext(); 243 void releaseContext(); 244 245 int save(int flags); 246 void restore(); 247 void restoreToCount(int saveCount); 248 249 int saveLayer(float left, float top, float right, float bottom, 250 SkPaint* p, int flags); 251 int saveLayerAlpha(float left, float top, float right, float bottom, 252 int alpha, int flags); 253 254 void translate(float dx, float dy); 255 void rotate(float degrees); 256 void scale(float sx, float sy); 257 void skew(float sx, float sy); 258 259 void setMatrix(SkMatrix* matrix); 260 void concatMatrix(SkMatrix* matrix); 261 262 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 263 264 void drawDisplayList(DisplayList* displayList, uint32_t level = 0); 265 void drawLayer(Layer* layer, float x, float y, SkPaint* paint); 266 void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 267 void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 268 void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 269 float srcRight, float srcBottom, float dstLeft, float dstTop, 270 float dstRight, float dstBottom, SkPaint* paint); 271 void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 272 float* vertices, int* colors, SkPaint* paint); 273 void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 274 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 275 float left, float top, float right, float bottom, SkPaint* paint); 276 void drawColor(int color, SkXfermode::Mode mode); 277 void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 278 void drawRoundRect(float left, float top, float right, float bottom, 279 float rx, float ry, SkPaint* paint); 280 void drawCircle(float x, float y, float radius, SkPaint* paint); 281 void drawPath(SkPath* path, SkPaint* paint); 282 void drawLines(float* points, int count, SkPaint* paint); 283 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 284 285 void resetShader(); 286 void setupShader(SkiaShader* shader); 287 288 void resetColorFilter(); 289 void setupColorFilter(SkiaColorFilter* filter); 290 291 void resetShadow(); 292 void setupShadow(float radius, float dx, float dy, int color); 293 294 void reset(); 295 296 const SkWriter32& writeStream() const { 297 return mWriter; 298 } 299 300 const Vector<SkBitmap*>& getBitmapResources() const { 301 return mBitmapResources; 302 } 303 304 const Vector<SkiaShader*>& getShaders() const { 305 return mShaders; 306 } 307 308 const Vector<SkPaint*>& getPaints() const { 309 return mPaints; 310 } 311 312 const Vector<SkMatrix*>& getMatrices() const { 313 return mMatrices; 314 } 315 316 const Vector<SkiaColorFilter*>& getFilterResources() const { 317 return mFilterResources; 318 } 319 320private: 321 inline void addOp(DisplayList::Op drawOp) { 322 mWriter.writeInt(drawOp); 323 } 324 325 inline void addInt(int value) { 326 mWriter.writeInt(value); 327 } 328 329 void addInts(const int32_t* values, uint32_t count) { 330 mWriter.writeInt(count); 331 for (uint32_t i = 0; i < count; i++) { 332 mWriter.writeInt(values[i]); 333 } 334 } 335 336 void addUInts(const uint32_t* values, int8_t count) { 337 mWriter.writeInt(count); 338 for (int8_t i = 0; i < count; i++) { 339 mWriter.writeInt(values[i]); 340 } 341 } 342 343 inline void addFloat(float value) { 344 mWriter.writeScalar(value); 345 } 346 347 void addFloats(const float* values, int count) { 348 mWriter.writeInt(count); 349 for (int i = 0; i < count; i++) { 350 mWriter.writeScalar(values[i]); 351 } 352 } 353 354 inline void addPoint(float x, float y) { 355 mWriter.writeScalar(x); 356 mWriter.writeScalar(y); 357 } 358 359 inline void addBounds(float left, float top, float right, float bottom) { 360 mWriter.writeScalar(left); 361 mWriter.writeScalar(top); 362 mWriter.writeScalar(right); 363 mWriter.writeScalar(bottom); 364 } 365 366 inline void addText(const void* text, size_t byteLength) { 367 mWriter.writeInt(byteLength); 368 mWriter.writePad(text, byteLength); 369 } 370 371 inline void addPath(const SkPath* path) { 372 if (mPathHeap == NULL) { 373 mPathHeap = new PathHeap(); 374 } 375 addInt(mPathHeap->append(*path)); 376 } 377 378 inline void addPaint(SkPaint* paint) { 379 if (!paint) { 380 addInt((int) NULL); 381 return; 382 } 383 384 SkPaint* paintCopy = mPaintMap.valueFor(paint); 385 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 386 paintCopy = new SkPaint(*paint); 387 mPaintMap.add(paint, paintCopy); 388 mPaints.add(paintCopy); 389 } 390 391 addInt((int) paintCopy); 392 } 393 394 inline void addDisplayList(DisplayList* displayList) { 395 // TODO: To be safe, the display list should be ref-counted in the 396 // resources cache, but we rely on the caller (UI toolkit) to 397 // do the right thing for now 398 addInt((int) displayList); 399 } 400 401 inline void addMatrix(SkMatrix* matrix) { 402 // Copying the matrix is cheap and prevents against the user changing the original 403 // matrix before the operation that uses it 404 addInt((int) new SkMatrix(*matrix)); 405 } 406 407 inline void addBitmap(SkBitmap* bitmap) { 408 // Note that this assumes the bitmap is immutable. There are cases this won't handle 409 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 410 // contents, and drawing again. The only fix would be to always copy it the first time, 411 // which doesn't seem worth the extra cycles for this unlikely case. 412 addInt((int) bitmap); 413 mBitmapResources.add(bitmap); 414 Caches& caches = Caches::getInstance(); 415 caches.resourceCache.incrementRefcount(bitmap); 416 } 417 418 inline void addShader(SkiaShader* shader) { 419 if (!shader) { 420 addInt((int) NULL); 421 return; 422 } 423 424 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 425 // TODO: We also need to handle generation ID changes in compose shaders 426 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 427 shaderCopy = shader->copy(); 428 mShaderMap.add(shader, shaderCopy); 429 mShaders.add(shaderCopy); 430 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 431 } 432 433 addInt((int) shaderCopy); 434 } 435 436 inline void addColorFilter(SkiaColorFilter* colorFilter) { 437 addInt((int) colorFilter); 438 mFilterResources.add(colorFilter); 439 Caches& caches = Caches::getInstance(); 440 caches.resourceCache.incrementRefcount(colorFilter); 441 } 442 443 SkChunkAlloc mHeap; 444 445 Vector<SkBitmap*> mBitmapResources; 446 Vector<SkiaColorFilter*> mFilterResources; 447 448 Vector<SkPaint*> mPaints; 449 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 450 451 Vector<SkiaShader*> mShaders; 452 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 453 454 Vector<SkMatrix*> mMatrices; 455 456 PathHeap* mPathHeap; 457 SkWriter32 mWriter; 458 459 SkRefCntRecorder mRCRecorder; 460 SkRefCntRecorder mTFRecorder; 461 462 DisplayList *mDisplayList; 463 464 friend class DisplayList; 465 466}; // class DisplayListRenderer 467 468}; // namespace uirenderer 469}; // namespace android 470 471#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 472