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