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