DisplayListRenderer.h revision 6c319ca1275c8db892c39b48fc54864c949f9171
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 32namespace android { 33namespace uirenderer { 34 35/////////////////////////////////////////////////////////////////////////////// 36// Defines 37/////////////////////////////////////////////////////////////////////////////// 38 39#define MIN_WRITER_SIZE 16384 40#define HEAP_BLOCK_SIZE 4096 41 42/////////////////////////////////////////////////////////////////////////////// 43// Helpers 44/////////////////////////////////////////////////////////////////////////////// 45 46class PathHeap: public SkRefCnt { 47public: 48 PathHeap(); 49 PathHeap(SkFlattenableReadBuffer& buffer); 50 ~PathHeap(); 51 52 int append(const SkPath& path); 53 54 int count() const { return mPaths.count(); } 55 56 SkPath& operator[](int index) const { 57 return *mPaths[index]; 58 } 59 60 void flatten(SkFlattenableWriteBuffer& buffer) const; 61 62private: 63 SkChunkAlloc mHeap; 64 SkTDArray<SkPath*> mPaths; 65}; 66 67/////////////////////////////////////////////////////////////////////////////// 68// Display list 69/////////////////////////////////////////////////////////////////////////////// 70 71class DisplayListRenderer; 72 73/** 74 * Replays recorded drawing commands. 75 */ 76class DisplayList { 77public: 78 DisplayList(const DisplayListRenderer& recorder); 79 ~DisplayList(); 80 81 enum Op { 82 AcquireContext, 83 ReleaseContext, 84 Save, 85 Restore, 86 RestoreToCount, 87 SaveLayer, 88 SaveLayerAlpha, 89 Translate, 90 Rotate, 91 Scale, 92 SetMatrix, 93 ConcatMatrix, 94 ClipRect, 95 DrawDisplayList, 96 DrawLayer, 97 DrawBitmap, 98 DrawBitmapMatrix, 99 DrawBitmapRect, 100 DrawPatch, 101 DrawColor, 102 DrawRect, 103 DrawPath, 104 DrawLines, 105 DrawText, 106 ResetShader, 107 SetupShader, 108 ResetColorFilter, 109 SetupColorFilter, 110 ResetShadow, 111 SetupShadow 112 }; 113 114 void initFromDisplayListRenderer(const DisplayListRenderer& recorder); 115 116 void replay(OpenGLRenderer& renderer); 117 118private: 119 void init(); 120 121 class TextContainer { 122 public: 123 size_t length() const { 124 return mByteLength; 125 } 126 127 const char* text() const { 128 return (const char*) mText; 129 } 130 131 size_t mByteLength; 132 const char* mText; 133 }; 134 135 SkBitmap* getBitmap() { 136 return (SkBitmap*) getInt(); 137 } 138 139 SkiaShader* getShader() { 140 return (SkiaShader*) getInt(); 141 } 142 143 SkiaColorFilter* getColorFilter() { 144 return (SkiaColorFilter*) getInt(); 145 } 146 147 inline int getIndex() { 148 return mReader.readInt(); 149 } 150 151 inline int getInt() { 152 return mReader.readInt(); 153 } 154 155 SkMatrix* getMatrix() { 156 return (SkMatrix*) getInt(); 157 } 158 159 SkPath* getPath() { 160 return &(*mPathHeap)[getInt() - 1]; 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 PathHeap* mPathHeap; 196 197 Vector<SkBitmap*> mBitmapResources; 198 Vector<SkiaShader*> mShaderResources; 199 Vector<SkiaColorFilter*> mFilterResources; 200 201 Vector<SkPaint*> mPaints; 202 Vector<SkMatrix*> mMatrices; 203 204 mutable SkFlattenableReadBuffer mReader; 205 206 SkRefCntPlayback mRCPlayback; 207 SkTypefacePlayback mTFPlayback; 208}; 209 210/////////////////////////////////////////////////////////////////////////////// 211// Renderer 212/////////////////////////////////////////////////////////////////////////////// 213 214/** 215 * Records drawing commands in a display list for latter playback. 216 */ 217class DisplayListRenderer: public OpenGLRenderer { 218public: 219 DisplayListRenderer(); 220 ~DisplayListRenderer(); 221 222 DisplayList* getDisplayList(); 223 224 void setViewport(int width, int height); 225 void prepare(bool opaque); 226 227 void acquireContext(); 228 void releaseContext(); 229 230 int save(int flags); 231 void restore(); 232 void restoreToCount(int saveCount); 233 234 int saveLayer(float left, float top, float right, float bottom, 235 SkPaint* p, int flags); 236 int saveLayerAlpha(float left, float top, float right, float bottom, 237 int alpha, int flags); 238 239 void translate(float dx, float dy); 240 void rotate(float degrees); 241 void scale(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 void drawDisplayList(DisplayList* displayList); 249 void drawLayer(int texture, float left, float top, float right, float bottom, 250 float u, float v, 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 drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 257 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 258 float left, float top, float right, float bottom, SkPaint* paint); 259 void drawColor(int color, SkXfermode::Mode mode); 260 void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 261 void drawPath(SkPath* path, SkPaint* paint); 262 void drawLines(float* points, int count, SkPaint* paint); 263 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 264 265 void resetShader(); 266 void setupShader(SkiaShader* shader); 267 268 void resetColorFilter(); 269 void setupColorFilter(SkiaColorFilter* filter); 270 271 void resetShadow(); 272 void setupShadow(float radius, float dx, float dy, int color); 273 274 void reset(); 275 276 const SkWriter32& writeStream() const { 277 return mWriter; 278 } 279 280 const Vector<SkBitmap*>& getBitmapResources() const { 281 return mBitmapResources; 282 } 283 284 const Vector<SkiaShader*>& getShaderResources() const { 285 return mShaderResources; 286 } 287 288 const Vector<SkPaint*>& getPaints() const { 289 return mPaints; 290 } 291 292 const Vector<SkMatrix*>& getMatrices() const { 293 return mMatrices; 294 } 295 296 const Vector<SkiaColorFilter*>& getFilterResources() const { 297 return mFilterResources; 298 } 299 300private: 301 inline void addOp(DisplayList::Op drawOp) { 302 mWriter.writeInt(drawOp); 303 } 304 305 inline void addInt(int value) { 306 mWriter.writeInt(value); 307 } 308 309 void addInts(const int32_t* values, uint32_t count) { 310 mWriter.writeInt(count); 311 for (uint32_t i = 0; i < count; i++) { 312 mWriter.writeInt(values[i]); 313 } 314 } 315 316 void addUInts(const uint32_t* values, int8_t count) { 317 mWriter.writeInt(count); 318 for (int8_t i = 0; i < count; i++) { 319 mWriter.writeInt(values[i]); 320 } 321 } 322 323 inline void addFloat(float value) { 324 mWriter.writeScalar(value); 325 } 326 327 void addFloats(const float* values, int count) { 328 mWriter.writeInt(count); 329 for (int i = 0; i < count; i++) { 330 mWriter.writeScalar(values[i]); 331 } 332 } 333 334 inline void addPoint(float x, float y) { 335 mWriter.writeScalar(x); 336 mWriter.writeScalar(y); 337 } 338 339 inline void addBounds(float left, float top, float right, float bottom) { 340 mWriter.writeScalar(left); 341 mWriter.writeScalar(top); 342 mWriter.writeScalar(right); 343 mWriter.writeScalar(bottom); 344 } 345 346 inline void addText(const void* text, size_t byteLength) { 347 mWriter.writeInt(byteLength); 348 mWriter.writePad(text, byteLength); 349 } 350 351 inline void addPath(const SkPath* path) { 352 if (mPathHeap == NULL) { 353 mPathHeap = new PathHeap(); 354 } 355 addInt(mPathHeap->append(*path)); 356 } 357 358 inline void addPaint(SkPaint* paint) { 359 if (paint == NULL) { 360 addInt((int) NULL); 361 return; 362 } 363 364 SkPaint *paintCopy = mPaintMap.valueFor(paint); 365 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 366 paintCopy = new SkPaint(*paint); 367 mPaintMap.add(paint, paintCopy); 368 mPaints.add(paintCopy); 369 } 370 371 addInt((int) paintCopy); 372 } 373 374 inline void addDisplayList(DisplayList* displayList) { 375 // TODO: To be safe, the display list should be ref-counted in the 376 // resources cache, but we rely on the caller (UI toolkit) to 377 // do the right thing for now 378 addInt((int) displayList); 379 } 380 381 inline void addMatrix(SkMatrix* matrix) { 382 // Copying the matrix is cheap and prevents against the user changing the original 383 // matrix before the operation that uses it 384 addInt((int) new SkMatrix(*matrix)); 385 } 386 387 inline void addBitmap(SkBitmap* bitmap) { 388 // Note that this assumes the bitmap is immutable. There are cases this won't handle 389 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 390 // contents, and drawing again. The only fix would be to always copy it the first time, 391 // which doesn't seem worth the extra cycles for this unlikely case. 392 addInt((int) bitmap); 393 mBitmapResources.add(bitmap); 394 Caches& caches = Caches::getInstance(); 395 caches.resourceCache.incrementRefcount(bitmap); 396 } 397 398 inline void addShader(SkiaShader* shader) { 399 addInt((int) shader); 400 mShaderResources.add(shader); 401 Caches& caches = Caches::getInstance(); 402 caches.resourceCache.incrementRefcount(shader); 403 } 404 405 inline void addColorFilter(SkiaColorFilter* colorFilter) { 406 addInt((int) colorFilter); 407 mFilterResources.add(colorFilter); 408 Caches& caches = Caches::getInstance(); 409 caches.resourceCache.incrementRefcount(colorFilter); 410 } 411 412 SkChunkAlloc mHeap; 413 414 Vector<SkBitmap*> mBitmapResources; 415 Vector<SkiaShader*> mShaderResources; 416 Vector<SkiaColorFilter*> mFilterResources; 417 418 Vector<SkPaint*> mPaints; 419 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 420 Vector<SkMatrix*> mMatrices; 421 422 PathHeap* mPathHeap; 423 SkWriter32 mWriter; 424 425 SkRefCntRecorder mRCRecorder; 426 SkRefCntRecorder mTFRecorder; 427 428 DisplayList *mDisplayList; 429 430 friend class DisplayList; 431 432}; // class DisplayListRenderer 433 434}; // namespace uirenderer 435}; // namespace android 436 437#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 438