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