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