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