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