DisplayListRenderer.h revision b051e895ccb696604349c6c5efe7c4747e1d1ab6
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(): mHeap(64 * sizeof(SkPath)) { 49 }; 50 51 PathHeap(SkFlattenableReadBuffer& buffer): mHeap(64 * sizeof(SkPath)) { 52 int count = buffer.readS32(); 53 54 mPaths.setCount(count); 55 SkPath** ptr = mPaths.begin(); 56 SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath)); 57 58 for (int i = 0; i < count; i++) { 59 new (p) SkPath; 60 p->unflatten(buffer); 61 *ptr++ = p; 62 p++; 63 } 64 } 65 66 ~PathHeap() { 67 SkPath** iter = mPaths.begin(); 68 SkPath** stop = mPaths.end(); 69 while (iter < stop) { 70 (*iter)->~SkPath(); 71 iter++; 72 } 73 } 74 75 int append(const SkPath& path) { 76 SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath)); 77 new (p) SkPath(path); 78 *mPaths.append() = p; 79 return mPaths.count(); 80 } 81 82 int count() const { return mPaths.count(); } 83 84 SkPath& operator[](int index) const { 85 return *mPaths[index]; 86 } 87 88 void flatten(SkFlattenableWriteBuffer& buffer) const { 89 int count = mPaths.count(); 90 91 buffer.write32(count); 92 SkPath** iter = mPaths.begin(); 93 SkPath** stop = mPaths.end(); 94 while (iter < stop) { 95 (*iter)->flatten(buffer); 96 iter++; 97 } 98 } 99 100private: 101 SkChunkAlloc mHeap; 102 SkTDArray<SkPath*> mPaths; 103}; 104 105/////////////////////////////////////////////////////////////////////////////// 106// Display list 107/////////////////////////////////////////////////////////////////////////////// 108 109class DisplayListRenderer; 110 111/** 112 * Replays recorded drawing commands. 113 */ 114class DisplayList { 115public: 116 DisplayList(const DisplayListRenderer& recorder); 117 ~DisplayList(); 118 119 enum Op { 120 AcquireContext, 121 ReleaseContext, 122 Save, 123 Restore, 124 RestoreToCount, 125 SaveLayer, 126 Translate, 127 Rotate, 128 Scale, 129 SetMatrix, 130 ConcatMatrix, 131 ClipRect, 132 DrawBitmap, 133 DrawBitmapMatrix, 134 DrawBitmapRect, 135 DrawPatch, 136 DrawColor, 137 DrawRect, 138 DrawPath, 139 DrawLines, 140 DrawText, 141 ResetShader, 142 SetupShader, 143 ResetColorFilter, 144 SetupColorFilter, 145 ResetShadow, 146 SetupShadow 147 }; 148 149 void replay(OpenGLRenderer& renderer); 150 151private: 152 void init(); 153 154 class TextContainer { 155 public: 156 size_t length() const { 157 return mByteLength; 158 } 159 160 const char* text() const { 161 return (const char*) mText; 162 } 163 164 size_t mByteLength; 165 const char* mText; 166 }; 167 168 SkBitmap* getBitmap() { 169 int index = getInt(); 170 return &mBitmaps[index - 1]; 171 } 172 173 inline int getIndex() { 174 return mReader.readInt(); 175 } 176 177 inline int getInt() { 178 return mReader.readInt(); 179 } 180 181 SkMatrix* getMatrix() { 182 int index = getInt(); 183 if (index == 0) { 184 return NULL; 185 } 186 return &mMatrices[index - 1]; 187 } 188 189 SkPath* getPath() { 190 return &(*mPathHeap)[getInt() - 1]; 191 } 192 193 SkPaint* getPaint() { 194 int index = getInt(); 195 if (index == 0) { 196 return NULL; 197 } 198 return &mPaints[index - 1]; 199 } 200 201 inline float getFloat() { 202 return mReader.readScalar(); 203 } 204 205 int32_t* getInts(uint32_t& count) { 206 count = getInt(); 207 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 208 } 209 210 float* getFloats(int& count) { 211 count = getInt(); 212 return (float*) mReader.skip(count * sizeof(float)); 213 } 214 215 void getText(TextContainer* text) { 216 size_t length = text->mByteLength = getInt(); 217 text->mText = (const char*) mReader.skip(length); 218 } 219 220 PathHeap* mPathHeap; 221 222 SkBitmap* mBitmaps; 223 int mBitmapCount; 224 225 SkMatrix* mMatrices; 226 int mMatrixCount; 227 228 SkPaint* mPaints; 229 int mPaintCount; 230 231 mutable SkFlattenableReadBuffer mReader; 232 233 SkRefCntPlayback mRCPlayback; 234 SkTypefacePlayback mTFPlayback; 235}; 236 237/////////////////////////////////////////////////////////////////////////////// 238// Renderer 239/////////////////////////////////////////////////////////////////////////////// 240 241/** 242 * Records drawing commands in a display list for latter playback. 243 */ 244class DisplayListRenderer: public OpenGLRenderer { 245public: 246 DisplayListRenderer(); 247 ~DisplayListRenderer(); 248 249 void setViewport(int width, int height); 250 void prepare(); 251 252 void acquireContext(); 253 void releaseContext(); 254 255 int save(int flags); 256 void restore(); 257 void restoreToCount(int saveCount); 258 259 int saveLayer(float left, float top, float right, float bottom, 260 const SkPaint* p, int flags); 261 262 void translate(float dx, float dy); 263 void rotate(float degrees); 264 void scale(float sx, float sy); 265 266 void setMatrix(SkMatrix* matrix); 267 void concatMatrix(SkMatrix* matrix); 268 269 bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 270 271 void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint); 272 void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint); 273 void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 274 float srcRight, float srcBottom, float dstLeft, float dstTop, 275 float dstRight, float dstBottom, const SkPaint* paint); 276 void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 277 uint32_t width, uint32_t height, float left, float top, float right, float bottom, 278 const SkPaint* paint); 279 void drawColor(int color, SkXfermode::Mode mode); 280 void drawRect(float left, float top, float right, float bottom, const SkPaint* paint); 281 void drawPath(SkPath* path, SkPaint* paint); 282 void drawLines(float* points, int count, const SkPaint* paint); 283 void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); 284 285 void resetShader(); 286 void setupShader(SkiaShader* shader); 287 288 void resetColorFilter(); 289 void setupColorFilter(SkiaColorFilter* filter); 290 291 void resetShadow(); 292 void setupShadow(float radius, float dx, float dy, int color); 293 294 void reset(); 295 296 DisplayList* getDisplayList() const { 297 return new DisplayList(*this); 298 } 299 300 const SkWriter32& writeStream() const { 301 return mWriter; 302 } 303 304 const SkTDArray<const SkFlatBitmap*>& getBitmaps() const { 305 return mBitmaps; 306 } 307 308 const SkTDArray<const SkFlatMatrix*>& getMatrices() const { 309 return mMatrices; 310 } 311 312 const SkTDArray<const SkFlatPaint*>& getPaints() const { 313 return mPaints; 314 } 315 316private: 317 inline void addOp(DisplayList::Op drawOp) { 318 mWriter.writeInt(drawOp); 319 } 320 321 inline void addInt(int value) { 322 mWriter.writeInt(value); 323 } 324 325 void addInts(const int32_t* values, uint32_t count) { 326 mWriter.writeInt(count); 327 for (uint32_t i = 0; i < count; i++) { 328 mWriter.writeInt(values[i]); 329 } 330 } 331 332 inline void addFloat(float value) { 333 mWriter.writeScalar(value); 334 } 335 336 void addFloats(const float* values, int count) { 337 mWriter.writeInt(count); 338 for (int i = 0; i < count; i++) { 339 mWriter.writeScalar(values[i]); 340 } 341 } 342 343 inline void addPoint(float x, float y) { 344 mWriter.writeScalar(x); 345 mWriter.writeScalar(y); 346 } 347 348 inline void addBounds(float left, float top, float right, float bottom) { 349 mWriter.writeScalar(left); 350 mWriter.writeScalar(top); 351 mWriter.writeScalar(right); 352 mWriter.writeScalar(bottom); 353 } 354 355 inline void addText(const void* text, size_t byteLength) { 356 mWriter.writeInt(byteLength); 357 mWriter.writePad(text, byteLength); 358 } 359 360 inline void addPath(const SkPath* path) { 361 if (mPathHeap == NULL) { 362 mPathHeap = new PathHeap(); 363 } 364 addInt(mPathHeap->append(*path)); 365 } 366 367 int find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint); 368 369 inline void addPaint(const SkPaint* paint) { 370 addInt(find(mPaints, paint)); 371 } 372 373 int find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix); 374 375 inline void addMatrix(const SkMatrix* matrix) { 376 addInt(find(mMatrices, matrix)); 377 } 378 379 int find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap); 380 381 inline void addBitmap(const SkBitmap* bitmap) { 382 addInt(find(mBitmaps, *bitmap)); 383 } 384 385 SkChunkAlloc mHeap; 386 387 int mBitmapIndex; 388 SkTDArray<const SkFlatBitmap*> mBitmaps; 389 390 int mMatrixIndex; 391 SkTDArray<const SkFlatMatrix*> mMatrices; 392 393 int mPaintIndex; 394 SkTDArray<const SkFlatPaint*> mPaints; 395 396 PathHeap* mPathHeap; 397 SkWriter32 mWriter; 398 399 SkRefCntRecorder mRCRecorder; 400 SkRefCntRecorder mTFRecorder; 401 402 friend class DisplayList; 403 404}; // class DisplayListRenderer 405 406}; // namespace uirenderer 407}; // namespace android 408 409#endif // ANDROID_UI_DISPLAY_LIST_RENDERER_H 410