DisplayListRenderer.h revision d98aa2de9ab18e09c2be1997f41212740f51f6e6
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 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 &(*mPathHeap)[getInt() - 1]; 152 } 153 154 SkPaint* getPaint() { 155 return (SkPaint*) getInt(); 156 } 157 158 inline float getFloat() { 159 return mReader.readScalar(); 160 } 161 162 int32_t* getInts(uint32_t& count) { 163 count = getInt(); 164 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 165 } 166 167 uint32_t* getUInts(int8_t& count) { 168 count = getInt(); 169 return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); 170 } 171 172 float* getFloats(int& count) { 173 count = getInt(); 174 return (float*) mReader.skip(count * sizeof(float)); 175 } 176 177 void getText(TextContainer* text) { 178 size_t length = text->mByteLength = getInt(); 179 text->mText = (const char*) mReader.skip(length); 180 } 181 182 PathHeap* mPathHeap; 183 184 Vector<SkBitmap*> mBitmapResources; 185 Vector<SkiaShader*> mShaderResources; 186 187 Vector<SkPaint*> mPaints; 188 Vector<SkMatrix*> mMatrices; 189 190 mutable SkFlattenableReadBuffer mReader; 191 192 SkRefCntPlayback mRCPlayback; 193 SkTypefacePlayback mTFPlayback; 194}; 195 196/////////////////////////////////////////////////////////////////////////////// 197// Renderer 198/////////////////////////////////////////////////////////////////////////////// 199 200/** 201 * Records drawing commands in a display list for latter playback. 202 */ 203class DisplayListRenderer: public OpenGLRenderer { 204public: 205 DisplayListRenderer(); 206 ~DisplayListRenderer(); 207 208 void setViewport(int width, int height); 209 void prepare(bool opaque); 210 211 void acquireContext(); 212 void releaseContext(); 213 214 int save(int flags); 215 void restore(); 216 void restoreToCount(int saveCount); 217 218 int saveLayer(float left, float top, float right, float bottom, 219 SkPaint* p, int flags); 220 221 void translate(float dx, float dy); 222 void rotate(float degrees); 223 void scale(float sx, float sy); 224 225 void setMatrix(SkMatrix* matrix); 226 void concatMatrix(SkMatrix* matrix); 227 228 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 229 230 void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 231 void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 232 void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 233 float srcRight, float srcBottom, float dstLeft, float dstTop, 234 float dstRight, float dstBottom, SkPaint* paint); 235 void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 236 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 237 float left, float top, float right, float bottom, SkPaint* paint); 238 void drawColor(int color, SkXfermode::Mode mode); 239 void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 240 void drawPath(SkPath* path, SkPaint* paint); 241 void drawLines(float* points, int count, SkPaint* paint); 242 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 243 244 void resetShader(); 245 void setupShader(SkiaShader* shader); 246 247 void resetColorFilter(); 248 void setupColorFilter(SkiaColorFilter* filter); 249 250 void resetShadow(); 251 void setupShadow(float radius, float dx, float dy, int color); 252 253 void reset(); 254 255 DisplayList* getDisplayList() const { 256 return new DisplayList(*this); 257 } 258 259 const SkWriter32& writeStream() const { 260 return mWriter; 261 } 262 263 const Vector<SkBitmap*>& getBitmapResources() const { 264 return mBitmapResources; 265 } 266 267 const Vector<SkiaShader*>& getShaderResources() const { 268 return mShaderResources; 269 } 270 271 const Vector<SkPaint*>& getPaints() const { 272 return mPaints; 273 } 274 275 const Vector<SkMatrix*>& getMatrices() const { 276 return mMatrices; 277 } 278 279private: 280 inline void addOp(DisplayList::Op drawOp) { 281 mWriter.writeInt(drawOp); 282 } 283 284 inline void addInt(int value) { 285 mWriter.writeInt(value); 286 } 287 288 void addInts(const int32_t* values, uint32_t count) { 289 mWriter.writeInt(count); 290 for (uint32_t i = 0; i < count; i++) { 291 mWriter.writeInt(values[i]); 292 } 293 } 294 295 void addUInts(const uint32_t* values, int8_t count) { 296 mWriter.writeInt(count); 297 for (int8_t i = 0; i < count; i++) { 298 mWriter.writeInt(values[i]); 299 } 300 } 301 302 inline void addFloat(float value) { 303 mWriter.writeScalar(value); 304 } 305 306 void addFloats(const float* values, int count) { 307 mWriter.writeInt(count); 308 for (int i = 0; i < count; i++) { 309 mWriter.writeScalar(values[i]); 310 } 311 } 312 313 inline void addPoint(float x, float y) { 314 mWriter.writeScalar(x); 315 mWriter.writeScalar(y); 316 } 317 318 inline void addBounds(float left, float top, float right, float bottom) { 319 mWriter.writeScalar(left); 320 mWriter.writeScalar(top); 321 mWriter.writeScalar(right); 322 mWriter.writeScalar(bottom); 323 } 324 325 inline void addText(const void* text, size_t byteLength) { 326 mWriter.writeInt(byteLength); 327 mWriter.writePad(text, byteLength); 328 } 329 330 inline void addPath(const SkPath* path) { 331 if (mPathHeap == NULL) { 332 mPathHeap = new PathHeap(); 333 } 334 addInt(mPathHeap->append(*path)); 335 } 336 337 inline void addPaint(SkPaint* paint) { 338 if (paint == NULL) { 339 addInt((int)NULL); 340 return; 341 } 342 SkPaint *paintCopy = mPaintMap.valueFor(paint); 343 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 344 paintCopy = new SkPaint(*paint); 345 mPaintMap.add(paint, paintCopy); 346 mPaints.add(paintCopy); 347 } 348 addInt((int)paintCopy); 349 } 350 351 inline void addMatrix(SkMatrix* matrix) { 352 // Copying the matrix is cheap and prevents against the user changing the original 353 // matrix before the operation that uses it 354 addInt((int) new SkMatrix(*matrix)); 355 } 356 357 inline void addBitmap(SkBitmap* bitmap) { 358 // Note that this assumes the bitmap is immutable. There are cases this won't handle 359 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 360 // contents, and drawing again. The only fix would be to always copy it the first time, 361 // which doesn't seem worth the extra cycles for this unlikely case. 362 addInt((int)bitmap); 363 mBitmapResources.add(bitmap); 364 Caches& caches = Caches::getInstance(); 365 caches.resourceCache.incrementRefcount(bitmap); 366 } 367 368 inline void addShader(SkiaShader* shader) { 369 addInt((int)shader); 370 mShaderResources.add(shader); 371 Caches& caches = Caches::getInstance(); 372 caches.resourceCache.incrementRefcount(shader); 373 } 374 375 SkChunkAlloc mHeap; 376 377 Vector<SkBitmap*> mBitmapResources; 378 Vector<SkiaShader*> mShaderResources; 379 380 Vector<SkPaint*> mPaints; 381 DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap; 382 Vector<SkMatrix*> mMatrices; 383 384 PathHeap* mPathHeap; 385 SkWriter32 mWriter; 386 387 SkRefCntRecorder mRCRecorder; 388 SkRefCntRecorder mTFRecorder; 389 390 friend class DisplayList; 391 392}; // class DisplayListRenderer 393 394}; // namespace uirenderer 395}; // namespace android 396 397#endif // ANDROID_UI_DISPLAY_LIST_RENDERER_H 398