DisplayListRenderer.h revision b29cfbf768eab959b31410aafc0a99e20249e9d7
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 <SkRefCnt.h> 26#include <SkTDArray.h> 27#include <SkTSearch.h> 28 29#include "OpenGLRenderer.h" 30#include "utils/Functor.h" 31 32namespace android { 33namespace uirenderer { 34 35/////////////////////////////////////////////////////////////////////////////// 36// Defines 37/////////////////////////////////////////////////////////////////////////////// 38 39#define MIN_WRITER_SIZE 16384 40 41// Debug 42#if DEBUG_DISPLAY_LIST 43 #define DISPLAY_LIST_LOGD(...) LOGD(__VA_ARGS__) 44#else 45 #define DISPLAY_LIST_LOGD(...) 46#endif 47 48/////////////////////////////////////////////////////////////////////////////// 49// Display list 50/////////////////////////////////////////////////////////////////////////////// 51 52class DisplayListRenderer; 53 54/** 55 * Replays recorded drawing commands. 56 */ 57class DisplayList { 58public: 59 DisplayList(const DisplayListRenderer& recorder); 60 ~DisplayList(); 61 62 // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file 63 // when modifying this file 64 enum Op { 65 Save = 0, 66 Restore, 67 RestoreToCount, 68 SaveLayer, 69 SaveLayerAlpha, 70 Translate, 71 Rotate, 72 Scale, 73 Skew, 74 SetMatrix, 75 ConcatMatrix, 76 ClipRect, 77 DrawDisplayList, 78 DrawLayer, 79 DrawBitmap, 80 DrawBitmapMatrix, 81 DrawBitmapRect, 82 DrawBitmapMesh, 83 DrawPatch, 84 DrawColor, 85 DrawRect, 86 DrawRoundRect, 87 DrawCircle, 88 DrawOval, 89 DrawArc, 90 DrawPath, 91 DrawLines, 92 DrawText, 93 ResetShader, 94 SetupShader, 95 ResetColorFilter, 96 SetupColorFilter, 97 ResetShadow, 98 SetupShadow, 99 DrawGLFunction, 100 }; 101 102 static const char* OP_NAMES[]; 103 104 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); 105 106 bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0); 107 108private: 109 void init(); 110 111 void clearResources(); 112 113 class TextContainer { 114 public: 115 size_t length() const { 116 return mByteLength; 117 } 118 119 const char* text() const { 120 return (const char*) mText; 121 } 122 123 size_t mByteLength; 124 const char* mText; 125 }; 126 127 SkBitmap* getBitmap() { 128 return (SkBitmap*) getInt(); 129 } 130 131 SkiaShader* getShader() { 132 return (SkiaShader*) getInt(); 133 } 134 135 SkiaColorFilter* getColorFilter() { 136 return (SkiaColorFilter*) getInt(); 137 } 138 139 inline int getIndex() { 140 return mReader.readInt(); 141 } 142 143 inline int getInt() { 144 return mReader.readInt(); 145 } 146 147 inline uint32_t getUInt() { 148 return mReader.readU32(); 149 } 150 151 SkMatrix* getMatrix() { 152 return (SkMatrix*) getInt(); 153 } 154 155 SkPath* getPath() { 156 return (SkPath*) getInt(); 157 } 158 159 SkPaint* getPaint() { 160 return (SkPaint*) getInt(); 161 } 162 163 DisplayList* getDisplayList() { 164 return (DisplayList*) getInt(); 165 } 166 167 inline float getFloat() { 168 return mReader.readScalar(); 169 } 170 171 int32_t* getInts(uint32_t& count) { 172 count = getInt(); 173 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 174 } 175 176 uint32_t* getUInts(int8_t& count) { 177 count = getInt(); 178 return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); 179 } 180 181 float* getFloats(int& count) { 182 count = getInt(); 183 return (float*) mReader.skip(count * sizeof(float)); 184 } 185 186 void getText(TextContainer* text) { 187 size_t length = text->mByteLength = getInt(); 188 text->mText = (const char*) mReader.skip(length); 189 } 190 191 Vector<SkBitmap*> mBitmapResources; 192 Vector<SkiaColorFilter*> mFilterResources; 193 194 Vector<SkPaint*> mPaints; 195 Vector<SkPath*> mPaths; 196 Vector<SkMatrix*> mMatrices; 197 Vector<SkiaShader*> mShaders; 198 199 mutable SkFlattenableReadBuffer mReader; 200}; 201 202/////////////////////////////////////////////////////////////////////////////// 203// Renderer 204/////////////////////////////////////////////////////////////////////////////// 205 206/** 207 * Records drawing commands in a display list for latter playback. 208 */ 209class DisplayListRenderer: public OpenGLRenderer { 210public: 211 DisplayListRenderer(); 212 ~DisplayListRenderer(); 213 214 DisplayList* getDisplayList(); 215 216 void setViewport(int width, int height); 217 void prepareDirty(float left, float top, float right, float bottom, bool opaque); 218 void finish(); 219 220 bool callDrawGLFunction(Functor *functor, Rect& dirty); 221 222 void interrupt(); 223 void resume(); 224 225 int save(int flags); 226 void restore(); 227 void restoreToCount(int saveCount); 228 229 int saveLayer(float left, float top, float right, float bottom, 230 SkPaint* p, int flags); 231 int saveLayerAlpha(float left, float top, float right, float bottom, 232 int alpha, int flags); 233 234 void translate(float dx, float dy); 235 void rotate(float degrees); 236 void scale(float sx, float sy); 237 void skew(float sx, float sy); 238 239 void setMatrix(SkMatrix* matrix); 240 void concatMatrix(SkMatrix* matrix); 241 242 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 243 244 bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height, 245 Rect& dirty, uint32_t level = 0); 246 void drawLayer(Layer* layer, float x, float y, SkPaint* paint); 247 void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 248 void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 249 void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 250 float srcRight, float srcBottom, float dstLeft, float dstTop, 251 float dstRight, float dstBottom, SkPaint* paint); 252 void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 253 float* vertices, int* colors, SkPaint* paint); 254 void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 255 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 256 float left, float top, float right, float bottom, SkPaint* paint); 257 void drawColor(int color, SkXfermode::Mode mode); 258 void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 259 void drawRoundRect(float left, float top, float right, float bottom, 260 float rx, float ry, SkPaint* paint); 261 void drawCircle(float x, float y, float radius, SkPaint* paint); 262 void drawOval(float left, float top, float right, float bottom, SkPaint* paint); 263 void drawArc(float left, float top, float right, float bottom, 264 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); 265 void drawPath(SkPath* path, SkPaint* paint); 266 void drawLines(float* points, int count, SkPaint* paint); 267 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 268 269 void resetShader(); 270 void setupShader(SkiaShader* shader); 271 272 void resetColorFilter(); 273 void setupColorFilter(SkiaColorFilter* filter); 274 275 void resetShadow(); 276 void setupShadow(float radius, float dx, float dy, int color); 277 278 void reset(); 279 280 const SkWriter32& writeStream() const { 281 return mWriter; 282 } 283 284 const Vector<SkBitmap*>& getBitmapResources() const { 285 return mBitmapResources; 286 } 287 288 const Vector<SkiaShader*>& getShaders() const { 289 return mShaders; 290 } 291 292 const Vector<SkPaint*>& getPaints() const { 293 return mPaints; 294 } 295 296 const Vector<SkPath*>& getPaths() const { 297 return mPaths; 298 } 299 300 const Vector<SkMatrix*>& getMatrices() const { 301 return mMatrices; 302 } 303 304 const Vector<SkiaColorFilter*>& getFilterResources() const { 305 return mFilterResources; 306 } 307 308private: 309 void insertRestoreToCount() { 310 if (mRestoreSaveCount >= 0) { 311 mWriter.writeInt(DisplayList::RestoreToCount); 312 addInt(mRestoreSaveCount); 313 mRestoreSaveCount = -1; 314 } 315 } 316 317 inline void addOp(DisplayList::Op drawOp) { 318 insertRestoreToCount(); 319 mWriter.writeInt(drawOp); 320 } 321 322 inline void addInt(int value) { 323 mWriter.writeInt(value); 324 } 325 326 inline void addSize(uint32_t w, uint32_t h) { 327 mWriter.writeInt(w); 328 mWriter.writeInt(h); 329 } 330 331 void addInts(const int32_t* values, uint32_t count) { 332 mWriter.writeInt(count); 333 for (uint32_t i = 0; i < count; i++) { 334 mWriter.writeInt(values[i]); 335 } 336 } 337 338 void addUInts(const uint32_t* values, int8_t count) { 339 mWriter.writeInt(count); 340 for (int8_t i = 0; i < count; i++) { 341 mWriter.writeInt(values[i]); 342 } 343 } 344 345 inline void addFloat(float value) { 346 mWriter.writeScalar(value); 347 } 348 349 void addFloats(const float* values, int count) { 350 mWriter.writeInt(count); 351 for (int i = 0; i < count; i++) { 352 mWriter.writeScalar(values[i]); 353 } 354 } 355 356 inline void addPoint(float x, float y) { 357 mWriter.writeScalar(x); 358 mWriter.writeScalar(y); 359 } 360 361 inline void addBounds(float left, float top, float right, float bottom) { 362 mWriter.writeScalar(left); 363 mWriter.writeScalar(top); 364 mWriter.writeScalar(right); 365 mWriter.writeScalar(bottom); 366 } 367 368 inline void addText(const void* text, size_t byteLength) { 369 mWriter.writeInt(byteLength); 370 mWriter.writePad(text, byteLength); 371 } 372 373 inline void addPath(SkPath* path) { 374 if (!path) { 375 addInt((int) NULL); 376 return; 377 } 378 379 SkPath* pathCopy = mPathMap.valueFor(path); 380 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 381 pathCopy = new SkPath(*path); 382 mPathMap.add(path, pathCopy); 383 mPaths.add(pathCopy); 384 } 385 386 addInt((int) pathCopy); 387 } 388 389 inline void addPaint(SkPaint* paint) { 390 if (!paint) { 391 addInt((int) NULL); 392 return; 393 } 394 395 SkPaint* paintCopy = mPaintMap.valueFor(paint); 396 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 397 paintCopy = new SkPaint(*paint); 398 mPaintMap.add(paint, paintCopy); 399 mPaints.add(paintCopy); 400 } 401 402 addInt((int) paintCopy); 403 } 404 405 inline void addDisplayList(DisplayList* displayList) { 406 // TODO: To be safe, the display list should be ref-counted in the 407 // resources cache, but we rely on the caller (UI toolkit) to 408 // do the right thing for now 409 addInt((int) displayList); 410 } 411 412 inline void addMatrix(SkMatrix* matrix) { 413 // Copying the matrix is cheap and prevents against the user changing the original 414 // matrix before the operation that uses it 415 addInt((int) new SkMatrix(*matrix)); 416 } 417 418 inline void addBitmap(SkBitmap* bitmap) { 419 // Note that this assumes the bitmap is immutable. There are cases this won't handle 420 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 421 // contents, and drawing again. The only fix would be to always copy it the first time, 422 // which doesn't seem worth the extra cycles for this unlikely case. 423 addInt((int) bitmap); 424 mBitmapResources.add(bitmap); 425 Caches& caches = Caches::getInstance(); 426 caches.resourceCache.incrementRefcount(bitmap); 427 } 428 429 inline void addShader(SkiaShader* shader) { 430 if (!shader) { 431 addInt((int) NULL); 432 return; 433 } 434 435 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 436 // TODO: We also need to handle generation ID changes in compose shaders 437 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 438 shaderCopy = shader->copy(); 439 mShaderMap.add(shader, shaderCopy); 440 mShaders.add(shaderCopy); 441 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 442 } 443 444 addInt((int) shaderCopy); 445 } 446 447 inline void addColorFilter(SkiaColorFilter* colorFilter) { 448 addInt((int) colorFilter); 449 mFilterResources.add(colorFilter); 450 Caches& caches = Caches::getInstance(); 451 caches.resourceCache.incrementRefcount(colorFilter); 452 } 453 454 Vector<SkBitmap*> mBitmapResources; 455 Vector<SkiaColorFilter*> mFilterResources; 456 457 Vector<SkPaint*> mPaints; 458 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 459 460 Vector<SkPath*> mPaths; 461 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 462 463 Vector<SkiaShader*> mShaders; 464 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 465 466 Vector<SkMatrix*> mMatrices; 467 468 SkWriter32 mWriter; 469 470 DisplayList *mDisplayList; 471 472 int mRestoreSaveCount; 473 474 friend class DisplayList; 475 476}; // class DisplayListRenderer 477 478}; // namespace uirenderer 479}; // namespace android 480 481#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 482