DisplayListRenderer.h revision ad93c2bb63dfc813b2eefa1043aa63afbddce655
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_UI_DISPLAY_LIST_RENDERER_H 18#define ANDROID_UI_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 Translate, 89 Rotate, 90 Scale, 91 SetMatrix, 92 ConcatMatrix, 93 ClipRect, 94 DrawBitmap, 95 DrawBitmapMatrix, 96 DrawBitmapRect, 97 DrawPatch, 98 DrawColor, 99 DrawRect, 100 DrawPath, 101 DrawLines, 102 DrawText, 103 ResetShader, 104 SetupShader, 105 ResetColorFilter, 106 SetupColorFilter, 107 ResetShadow, 108 SetupShadow 109 }; 110 111 void replay(OpenGLRenderer& renderer); 112 113private: 114 void init(); 115 116 class TextContainer { 117 public: 118 size_t length() const { 119 return mByteLength; 120 } 121 122 const char* text() const { 123 return (const char*) mText; 124 } 125 126 size_t mByteLength; 127 const char* mText; 128 }; 129 130 SkBitmap* getBitmap() { 131 return (SkBitmap*) getInt(); 132 } 133 134 SkiaShader* getShader() { 135 return (SkiaShader*) getInt(); 136 } 137 138 SkiaColorFilter* getColorFilter() { 139 return (SkiaColorFilter*) getInt(); 140 } 141 142 inline int getIndex() { 143 return mReader.readInt(); 144 } 145 146 inline int getInt() { 147 return mReader.readInt(); 148 } 149 150 SkMatrix* getMatrix() { 151 return (SkMatrix*) getInt(); 152 } 153 154 SkPath* getPath() { 155 return &(*mPathHeap)[getInt() - 1]; 156 } 157 158 SkPaint* getPaint() { 159 return (SkPaint*) 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 PathHeap* mPathHeap; 187 188 Vector<SkBitmap*> mBitmapResources; 189 Vector<SkiaShader*> mShaderResources; 190 Vector<SkiaColorFilter*> mFilterResources; 191 192 Vector<SkPaint*> mPaints; 193 Vector<SkMatrix*> mMatrices; 194 195 mutable SkFlattenableReadBuffer mReader; 196 197 SkRefCntPlayback mRCPlayback; 198 SkTypefacePlayback mTFPlayback; 199}; 200 201/////////////////////////////////////////////////////////////////////////////// 202// Renderer 203/////////////////////////////////////////////////////////////////////////////// 204 205/** 206 * Records drawing commands in a display list for latter playback. 207 */ 208class DisplayListRenderer: public OpenGLRenderer { 209public: 210 DisplayListRenderer(); 211 ~DisplayListRenderer(); 212 213 void setViewport(int width, int height); 214 void prepare(bool opaque); 215 216 void acquireContext(); 217 void releaseContext(); 218 219 int save(int flags); 220 void restore(); 221 void restoreToCount(int saveCount); 222 223 int saveLayer(float left, float top, float right, float bottom, 224 SkPaint* p, int flags); 225 226 void translate(float dx, float dy); 227 void rotate(float degrees); 228 void scale(float sx, float sy); 229 230 void setMatrix(SkMatrix* matrix); 231 void concatMatrix(SkMatrix* matrix); 232 233 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 234 235 void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 236 void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 237 void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 238 float srcRight, float srcBottom, float dstLeft, float dstTop, 239 float dstRight, float dstBottom, SkPaint* paint); 240 void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 241 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 242 float left, float top, float right, float bottom, SkPaint* paint); 243 void drawColor(int color, SkXfermode::Mode mode); 244 void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 245 void drawPath(SkPath* path, SkPaint* paint); 246 void drawLines(float* points, int count, SkPaint* paint); 247 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 248 249 void resetShader(); 250 void setupShader(SkiaShader* shader); 251 252 void resetColorFilter(); 253 void setupColorFilter(SkiaColorFilter* filter); 254 255 void resetShadow(); 256 void setupShadow(float radius, float dx, float dy, int color); 257 258 void reset(); 259 260 DisplayList* getDisplayList() const { 261 return new DisplayList(*this); 262 } 263 264 const SkWriter32& writeStream() const { 265 return mWriter; 266 } 267 268 const Vector<SkBitmap*>& getBitmapResources() const { 269 return mBitmapResources; 270 } 271 272 const Vector<SkiaShader*>& getShaderResources() const { 273 return mShaderResources; 274 } 275 276 const Vector<SkPaint*>& getPaints() const { 277 return mPaints; 278 } 279 280 const Vector<SkMatrix*>& getMatrices() const { 281 return mMatrices; 282 } 283 284 const Vector<SkiaColorFilter*>& getFilterResources() const { 285 return mFilterResources; 286 } 287 288private: 289 inline void addOp(DisplayList::Op drawOp) { 290 mWriter.writeInt(drawOp); 291 } 292 293 inline void addInt(int value) { 294 mWriter.writeInt(value); 295 } 296 297 void addInts(const int32_t* values, uint32_t count) { 298 mWriter.writeInt(count); 299 for (uint32_t i = 0; i < count; i++) { 300 mWriter.writeInt(values[i]); 301 } 302 } 303 304 void addUInts(const uint32_t* values, int8_t count) { 305 mWriter.writeInt(count); 306 for (int8_t i = 0; i < count; i++) { 307 mWriter.writeInt(values[i]); 308 } 309 } 310 311 inline void addFloat(float value) { 312 mWriter.writeScalar(value); 313 } 314 315 void addFloats(const float* values, int count) { 316 mWriter.writeInt(count); 317 for (int i = 0; i < count; i++) { 318 mWriter.writeScalar(values[i]); 319 } 320 } 321 322 inline void addPoint(float x, float y) { 323 mWriter.writeScalar(x); 324 mWriter.writeScalar(y); 325 } 326 327 inline void addBounds(float left, float top, float right, float bottom) { 328 mWriter.writeScalar(left); 329 mWriter.writeScalar(top); 330 mWriter.writeScalar(right); 331 mWriter.writeScalar(bottom); 332 } 333 334 inline void addText(const void* text, size_t byteLength) { 335 mWriter.writeInt(byteLength); 336 mWriter.writePad(text, byteLength); 337 } 338 339 inline void addPath(const SkPath* path) { 340 if (mPathHeap == NULL) { 341 mPathHeap = new PathHeap(); 342 } 343 addInt(mPathHeap->append(*path)); 344 } 345 346 inline void addPaint(SkPaint* paint) { 347 if (paint == NULL) { 348 addInt((int)NULL); 349 return; 350 } 351 SkPaint *paintCopy = mPaintMap.valueFor(paint); 352 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 353 paintCopy = new SkPaint(*paint); 354 mPaintMap.add(paint, paintCopy); 355 mPaints.add(paintCopy); 356 } 357 addInt((int)paintCopy); 358 } 359 360 inline void addMatrix(SkMatrix* matrix) { 361 // Copying the matrix is cheap and prevents against the user changing the original 362 // matrix before the operation that uses it 363 addInt((int) new SkMatrix(*matrix)); 364 } 365 366 inline void addBitmap(SkBitmap* bitmap) { 367 // Note that this assumes the bitmap is immutable. There are cases this won't handle 368 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 369 // contents, and drawing again. The only fix would be to always copy it the first time, 370 // which doesn't seem worth the extra cycles for this unlikely case. 371 addInt((int)bitmap); 372 mBitmapResources.add(bitmap); 373 Caches& caches = Caches::getInstance(); 374 caches.resourceCache.incrementRefcount(bitmap); 375 } 376 377 inline void addShader(SkiaShader* shader) { 378 addInt((int)shader); 379 mShaderResources.add(shader); 380 Caches& caches = Caches::getInstance(); 381 caches.resourceCache.incrementRefcount(shader); 382 } 383 384 inline void addColorFilter(SkiaColorFilter* colorFilter) { 385 addInt((int)colorFilter); 386 mFilterResources.add(colorFilter); 387 Caches& caches = Caches::getInstance(); 388 caches.resourceCache.incrementRefcount(colorFilter); 389 } 390 391 SkChunkAlloc mHeap; 392 393 Vector<SkBitmap*> mBitmapResources; 394 Vector<SkiaShader*> mShaderResources; 395 Vector<SkiaColorFilter*> mFilterResources; 396 397 Vector<SkPaint*> mPaints; 398 DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap; 399 Vector<SkMatrix*> mMatrices; 400 401 PathHeap* mPathHeap; 402 SkWriter32 mWriter; 403 404 SkRefCntRecorder mRCRecorder; 405 SkRefCntRecorder mTFRecorder; 406 407 friend class DisplayList; 408 409}; // class DisplayListRenderer 410 411}; // namespace uirenderer 412}; // namespace android 413 414#endif // ANDROID_UI_DISPLAY_LIST_RENDERER_H 415