DisplayListRenderer.h revision d63cbd10765e8f48e39b07b15f0a4b70bf853ec8
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#include "utils/Functor.h" 32 33namespace android { 34namespace uirenderer { 35 36/////////////////////////////////////////////////////////////////////////////// 37// Defines 38/////////////////////////////////////////////////////////////////////////////// 39 40#define MIN_WRITER_SIZE 16384 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// Display list 51/////////////////////////////////////////////////////////////////////////////// 52 53class DisplayListRenderer; 54 55/** 56 * Replays recorded drawing commands. 57 */ 58class DisplayList { 59public: 60 DisplayList(const DisplayListRenderer& recorder); 61 ~DisplayList(); 62 63 // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file 64 // when modifying this file 65 enum Op { 66 Save = 0, 67 Restore, 68 RestoreToCount, 69 SaveLayer, 70 SaveLayerAlpha, 71 Translate, 72 Rotate, 73 Scale, 74 Skew, 75 SetMatrix, 76 ConcatMatrix, 77 ClipRect, 78 DrawDisplayList, 79 DrawLayer, 80 DrawBitmap, 81 DrawBitmapMatrix, 82 DrawBitmapRect, 83 DrawBitmapMesh, 84 DrawPatch, 85 DrawColor, 86 DrawRect, 87 DrawRoundRect, 88 DrawCircle, 89 DrawOval, 90 DrawArc, 91 DrawPath, 92 DrawLines, 93 DrawText, 94 ResetShader, 95 SetupShader, 96 ResetColorFilter, 97 SetupColorFilter, 98 ResetShadow, 99 SetupShadow, 100 DrawGLFunction, 101 }; 102 103 static const char* OP_NAMES[]; 104 105 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); 106 107 bool replay(OpenGLRenderer& renderer, uint32_t level = 0); 108 109private: 110 void init(); 111 112 void clearResources(); 113 114 class TextContainer { 115 public: 116 size_t length() const { 117 return mByteLength; 118 } 119 120 const char* text() const { 121 return (const char*) mText; 122 } 123 124 size_t mByteLength; 125 const char* mText; 126 }; 127 128 SkBitmap* getBitmap() { 129 return (SkBitmap*) getInt(); 130 } 131 132 SkiaShader* getShader() { 133 return (SkiaShader*) getInt(); 134 } 135 136 SkiaColorFilter* getColorFilter() { 137 return (SkiaColorFilter*) getInt(); 138 } 139 140 inline int getIndex() { 141 return mReader.readInt(); 142 } 143 144 inline int getInt() { 145 return mReader.readInt(); 146 } 147 148 SkMatrix* getMatrix() { 149 return (SkMatrix*) getInt(); 150 } 151 152 SkPath* getPath() { 153 return (SkPath*) getInt(); 154 } 155 156 SkPaint* getPaint() { 157 return (SkPaint*) getInt(); 158 } 159 160 DisplayList* getDisplayList() { 161 return (DisplayList*) getInt(); 162 } 163 164 inline float getFloat() { 165 return mReader.readScalar(); 166 } 167 168 int32_t* getInts(uint32_t& count) { 169 count = getInt(); 170 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 171 } 172 173 uint32_t* getUInts(int8_t& count) { 174 count = getInt(); 175 return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); 176 } 177 178 float* getFloats(int& count) { 179 count = getInt(); 180 return (float*) mReader.skip(count * sizeof(float)); 181 } 182 183 void getText(TextContainer* text) { 184 size_t length = text->mByteLength = getInt(); 185 text->mText = (const char*) mReader.skip(length); 186 } 187 188 Vector<SkBitmap*> mBitmapResources; 189 Vector<SkiaColorFilter*> mFilterResources; 190 191 Vector<SkPaint*> mPaints; 192 Vector<SkPath*> mPaths; 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); 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, 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<SkMatrix*>& getMatrices() const { 297 return mMatrices; 298 } 299 300 const Vector<SkiaColorFilter*>& getFilterResources() const { 301 return mFilterResources; 302 } 303 304private: 305 void insertRestoreToCount() { 306 if (mRestoreSaveCount >= 0) { 307 mWriter.writeInt(DisplayList::RestoreToCount); 308 addInt(mRestoreSaveCount); 309 mRestoreSaveCount = -1; 310 } 311 } 312 313 inline void addOp(DisplayList::Op drawOp) { 314 insertRestoreToCount(); 315 mWriter.writeInt(drawOp); 316 } 317 318 inline void addInt(int value) { 319 mWriter.writeInt(value); 320 } 321 322 void addInts(const int32_t* values, uint32_t count) { 323 mWriter.writeInt(count); 324 for (uint32_t i = 0; i < count; i++) { 325 mWriter.writeInt(values[i]); 326 } 327 } 328 329 void addUInts(const uint32_t* values, int8_t count) { 330 mWriter.writeInt(count); 331 for (int8_t i = 0; i < count; i++) { 332 mWriter.writeInt(values[i]); 333 } 334 } 335 336 inline void addFloat(float value) { 337 mWriter.writeScalar(value); 338 } 339 340 void addFloats(const float* values, int count) { 341 mWriter.writeInt(count); 342 for (int i = 0; i < count; i++) { 343 mWriter.writeScalar(values[i]); 344 } 345 } 346 347 inline void addPoint(float x, float y) { 348 mWriter.writeScalar(x); 349 mWriter.writeScalar(y); 350 } 351 352 inline void addBounds(float left, float top, float right, float bottom) { 353 mWriter.writeScalar(left); 354 mWriter.writeScalar(top); 355 mWriter.writeScalar(right); 356 mWriter.writeScalar(bottom); 357 } 358 359 inline void addText(const void* text, size_t byteLength) { 360 mWriter.writeInt(byteLength); 361 mWriter.writePad(text, byteLength); 362 } 363 364 inline void addPath(SkPath* path) { 365 if (!path) { 366 addInt((int) NULL); 367 return; 368 } 369 370 SkPath* pathCopy = mPathMap.valueFor(path); 371 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 372 if (pathCopy == NULL) { 373 pathCopy = path; 374 } else { 375 pathCopy = new SkPath(*path); 376 mPaths.add(pathCopy); 377 } 378 mPathMap.add(path, pathCopy); 379 } 380 381 addInt((int) pathCopy); 382 } 383 384 inline void addPaint(SkPaint* paint) { 385 if (!paint) { 386 addInt((int) NULL); 387 return; 388 } 389 390 SkPaint* paintCopy = mPaintMap.valueFor(paint); 391 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 392 paintCopy = new SkPaint(*paint); 393 mPaintMap.add(paint, paintCopy); 394 mPaints.add(paintCopy); 395 } 396 397 addInt((int) paintCopy); 398 } 399 400 inline void addDisplayList(DisplayList* displayList) { 401 // TODO: To be safe, the display list should be ref-counted in the 402 // resources cache, but we rely on the caller (UI toolkit) to 403 // do the right thing for now 404 addInt((int) displayList); 405 } 406 407 inline void addMatrix(SkMatrix* matrix) { 408 // Copying the matrix is cheap and prevents against the user changing the original 409 // matrix before the operation that uses it 410 addInt((int) new SkMatrix(*matrix)); 411 } 412 413 inline void addBitmap(SkBitmap* bitmap) { 414 // Note that this assumes the bitmap is immutable. There are cases this won't handle 415 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 416 // contents, and drawing again. The only fix would be to always copy it the first time, 417 // which doesn't seem worth the extra cycles for this unlikely case. 418 addInt((int) bitmap); 419 mBitmapResources.add(bitmap); 420 Caches& caches = Caches::getInstance(); 421 caches.resourceCache.incrementRefcount(bitmap); 422 } 423 424 inline void addShader(SkiaShader* shader) { 425 if (!shader) { 426 addInt((int) NULL); 427 return; 428 } 429 430 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 431 // TODO: We also need to handle generation ID changes in compose shaders 432 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 433 shaderCopy = shader->copy(); 434 mShaderMap.add(shader, shaderCopy); 435 mShaders.add(shaderCopy); 436 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 437 } 438 439 addInt((int) shaderCopy); 440 } 441 442 inline void addColorFilter(SkiaColorFilter* colorFilter) { 443 addInt((int) colorFilter); 444 mFilterResources.add(colorFilter); 445 Caches& caches = Caches::getInstance(); 446 caches.resourceCache.incrementRefcount(colorFilter); 447 } 448 449 Vector<SkBitmap*> mBitmapResources; 450 Vector<SkiaColorFilter*> mFilterResources; 451 452 Vector<SkPaint*> mPaints; 453 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 454 455 Vector<SkPath*> mPaths; 456 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 457 458 Vector<SkiaShader*> mShaders; 459 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 460 461 Vector<SkMatrix*> mMatrices; 462 463 SkWriter32 mWriter; 464 465 DisplayList *mDisplayList; 466 467 int mRestoreSaveCount; 468 469 friend class DisplayList; 470 471}; // class DisplayListRenderer 472 473}; // namespace uirenderer 474}; // namespace android 475 476#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 477