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