DisplayListRenderer.h revision cabfcc1364eb7e4de0b15b3574fba45027b45cfc
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 SkMatrix* getMatrix() { 148 return (SkMatrix*) getInt(); 149 } 150 151 SkPath* getPath() { 152 return (SkPath*) getInt(); 153 } 154 155 SkPaint* getPaint() { 156 return (SkPaint*) getInt(); 157 } 158 159 DisplayList* getDisplayList() { 160 return (DisplayList*) getInt(); 161 } 162 163 inline float getFloat() { 164 return mReader.readScalar(); 165 } 166 167 int32_t* getInts(uint32_t& count) { 168 count = getInt(); 169 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 170 } 171 172 uint32_t* getUInts(int8_t& count) { 173 count = getInt(); 174 return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); 175 } 176 177 float* getFloats(int& count) { 178 count = getInt(); 179 return (float*) mReader.skip(count * sizeof(float)); 180 } 181 182 void getText(TextContainer* text) { 183 size_t length = text->mByteLength = getInt(); 184 text->mText = (const char*) mReader.skip(length); 185 } 186 187 Vector<SkBitmap*> mBitmapResources; 188 Vector<SkiaColorFilter*> mFilterResources; 189 190 Vector<SkPaint*> mPaints; 191 Vector<SkPath*> mPaths; 192 Vector<SkPath*> mOriginalPaths; 193 Vector<SkMatrix*> mMatrices; 194 Vector<SkiaShader*> mShaders; 195 196 mutable SkFlattenableReadBuffer mReader; 197}; 198 199/////////////////////////////////////////////////////////////////////////////// 200// Renderer 201/////////////////////////////////////////////////////////////////////////////// 202 203/** 204 * Records drawing commands in a display list for latter playback. 205 */ 206class DisplayListRenderer: public OpenGLRenderer { 207public: 208 DisplayListRenderer(); 209 ~DisplayListRenderer(); 210 211 DisplayList* getDisplayList(); 212 213 void setViewport(int width, int height); 214 void prepareDirty(float left, float top, float right, float bottom, bool opaque); 215 void finish(); 216 217 bool callDrawGLFunction(Functor *functor, Rect& dirty); 218 219 void interrupt(); 220 void resume(); 221 222 int save(int flags); 223 void restore(); 224 void restoreToCount(int saveCount); 225 226 int saveLayer(float left, float top, float right, float bottom, 227 SkPaint* p, int flags); 228 int saveLayerAlpha(float left, float top, float right, float bottom, 229 int alpha, int flags); 230 231 void translate(float dx, float dy); 232 void rotate(float degrees); 233 void scale(float sx, float sy); 234 void skew(float sx, float sy); 235 236 void setMatrix(SkMatrix* matrix); 237 void concatMatrix(SkMatrix* matrix); 238 239 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 240 241 bool drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level = 0); 242 void drawLayer(Layer* layer, float x, float y, SkPaint* paint); 243 void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 244 void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 245 void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 246 float srcRight, float srcBottom, float dstLeft, float dstTop, 247 float dstRight, float dstBottom, SkPaint* paint); 248 void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 249 float* vertices, int* colors, SkPaint* paint); 250 void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 251 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 252 float left, float top, float right, float bottom, SkPaint* paint); 253 void drawColor(int color, SkXfermode::Mode mode); 254 void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 255 void drawRoundRect(float left, float top, float right, float bottom, 256 float rx, float ry, SkPaint* paint); 257 void drawCircle(float x, float y, float radius, SkPaint* paint); 258 void drawOval(float left, float top, float right, float bottom, SkPaint* paint); 259 void drawArc(float left, float top, float right, float bottom, 260 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); 261 void drawPath(SkPath* path, SkPaint* paint); 262 void drawLines(float* points, int count, SkPaint* paint); 263 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 264 265 void resetShader(); 266 void setupShader(SkiaShader* shader); 267 268 void resetColorFilter(); 269 void setupColorFilter(SkiaColorFilter* filter); 270 271 void resetShadow(); 272 void setupShadow(float radius, float dx, float dy, int color); 273 274 void reset(); 275 276 const SkWriter32& writeStream() const { 277 return mWriter; 278 } 279 280 const Vector<SkBitmap*>& getBitmapResources() const { 281 return mBitmapResources; 282 } 283 284 const Vector<SkiaShader*>& getShaders() const { 285 return mShaders; 286 } 287 288 const Vector<SkPaint*>& getPaints() const { 289 return mPaints; 290 } 291 292 const Vector<SkPath*>& getPaths() const { 293 return mPaths; 294 } 295 296 const Vector<SkPath*>& getOriginalPaths() const { 297 return mOriginalPaths; 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 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(SkPath* path) { 369 if (!path) { 370 addInt((int) NULL); 371 return; 372 } 373 374 SkPath* pathCopy = mPathMap.valueFor(path); 375 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 376 if (pathCopy == NULL) { 377 pathCopy = path; 378 mOriginalPaths.add(path); 379 Caches& caches = Caches::getInstance(); 380 caches.resourceCache.incrementRefcount(path); 381 } else { 382 pathCopy = new SkPath(*path); 383 mPaths.add(pathCopy); 384 } 385 mPathMap.add(path, pathCopy); 386 } 387 388 addInt((int) pathCopy); 389 } 390 391 inline void addPaint(SkPaint* paint) { 392 if (!paint) { 393 addInt((int) NULL); 394 return; 395 } 396 397 SkPaint* paintCopy = mPaintMap.valueFor(paint); 398 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 399 paintCopy = new SkPaint(*paint); 400 mPaintMap.add(paint, paintCopy); 401 mPaints.add(paintCopy); 402 } 403 404 addInt((int) paintCopy); 405 } 406 407 inline void addDisplayList(DisplayList* displayList) { 408 // TODO: To be safe, the display list should be ref-counted in the 409 // resources cache, but we rely on the caller (UI toolkit) to 410 // do the right thing for now 411 addInt((int) displayList); 412 } 413 414 inline void addMatrix(SkMatrix* matrix) { 415 // Copying the matrix is cheap and prevents against the user changing the original 416 // matrix before the operation that uses it 417 addInt((int) new SkMatrix(*matrix)); 418 } 419 420 inline void addBitmap(SkBitmap* bitmap) { 421 // Note that this assumes the bitmap is immutable. There are cases this won't handle 422 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 423 // contents, and drawing again. The only fix would be to always copy it the first time, 424 // which doesn't seem worth the extra cycles for this unlikely case. 425 addInt((int) bitmap); 426 mBitmapResources.add(bitmap); 427 Caches& caches = Caches::getInstance(); 428 caches.resourceCache.incrementRefcount(bitmap); 429 } 430 431 inline void addShader(SkiaShader* shader) { 432 if (!shader) { 433 addInt((int) NULL); 434 return; 435 } 436 437 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 438 // TODO: We also need to handle generation ID changes in compose shaders 439 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 440 shaderCopy = shader->copy(); 441 mShaderMap.add(shader, shaderCopy); 442 mShaders.add(shaderCopy); 443 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 444 } 445 446 addInt((int) shaderCopy); 447 } 448 449 inline void addColorFilter(SkiaColorFilter* colorFilter) { 450 addInt((int) colorFilter); 451 mFilterResources.add(colorFilter); 452 Caches& caches = Caches::getInstance(); 453 caches.resourceCache.incrementRefcount(colorFilter); 454 } 455 456 Vector<SkBitmap*> mBitmapResources; 457 Vector<SkiaColorFilter*> mFilterResources; 458 459 Vector<SkPaint*> mPaints; 460 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 461 462 Vector<SkPath*> mOriginalPaths; 463 Vector<SkPath*> mPaths; 464 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 465 466 Vector<SkiaShader*> mShaders; 467 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 468 469 Vector<SkMatrix*> mMatrices; 470 471 SkWriter32 mWriter; 472 473 DisplayList *mDisplayList; 474 475 int mRestoreSaveCount; 476 477 friend class DisplayList; 478 479}; // class DisplayListRenderer 480 481}; // namespace uirenderer 482}; // namespace android 483 484#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 485