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