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