DisplayListRenderer.h revision 4bb942083a0d4db746adf95349108dd8ef842e32
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 int index = getInt(); 132 return &mBitmaps[index - 1]; 133 } 134 135 inline int getIndex() { 136 return mReader.readInt(); 137 } 138 139 inline int getInt() { 140 return mReader.readInt(); 141 } 142 143 SkMatrix* getMatrix() { 144 int index = getInt(); 145 if (index == 0) { 146 return NULL; 147 } 148 return &mMatrices[index - 1]; 149 } 150 151 SkPath* getPath() { 152 return &(*mPathHeap)[getInt() - 1]; 153 } 154 155 SkPaint* getPaint() { 156 int index = getInt(); 157 if (index == 0) { 158 return NULL; 159 } 160 return &mPaints[index - 1]; 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 SkBitmap* mBitmaps; 190 int mBitmapCount; 191 192 SkMatrix* mMatrices; 193 int mMatrixCount; 194 195 SkPaint* mPaints; 196 int mPaintCount; 197 198 mutable SkFlattenableReadBuffer mReader; 199 200 SkRefCntPlayback mRCPlayback; 201 SkTypefacePlayback mTFPlayback; 202}; 203 204/////////////////////////////////////////////////////////////////////////////// 205// Renderer 206/////////////////////////////////////////////////////////////////////////////// 207 208/** 209 * Records drawing commands in a display list for latter playback. 210 */ 211class DisplayListRenderer: public OpenGLRenderer { 212public: 213 DisplayListRenderer(); 214 ~DisplayListRenderer(); 215 216 void setViewport(int width, int height); 217 void prepare(bool opaque); 218 219 void acquireContext(); 220 void releaseContext(); 221 222 int save(int flags); 223 void restore(); 224 void restoreToCount(int saveCount); 225 226 int saveLayer(float left, float top, float right, float bottom, 227 const SkPaint* p, 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, const SkPaint* paint); 239 void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const 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, const 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, const SkPaint* paint); 246 void drawColor(int color, SkXfermode::Mode mode); 247 void drawRect(float left, float top, float right, float bottom, const SkPaint* paint); 248 void drawPath(SkPath* path, SkPaint* paint); 249 void drawLines(float* points, int count, const 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 SkTDArray<const SkFlatBitmap*>& getBitmaps() const { 272 return mBitmaps; 273 } 274 275 const SkTDArray<const SkFlatMatrix*>& getMatrices() const { 276 return mMatrices; 277 } 278 279 const SkTDArray<const SkFlatPaint*>& getPaints() const { 280 return mPaints; 281 } 282 283private: 284 inline void addOp(DisplayList::Op drawOp) { 285 mWriter.writeInt(drawOp); 286 } 287 288 inline void addInt(int value) { 289 mWriter.writeInt(value); 290 } 291 292 void addInts(const int32_t* values, uint32_t count) { 293 mWriter.writeInt(count); 294 for (uint32_t i = 0; i < count; i++) { 295 mWriter.writeInt(values[i]); 296 } 297 } 298 299 void addUInts(const uint32_t* values, int8_t count) { 300 mWriter.writeInt(count); 301 for (int8_t i = 0; i < count; i++) { 302 mWriter.writeInt(values[i]); 303 } 304 } 305 306 inline void addFloat(float value) { 307 mWriter.writeScalar(value); 308 } 309 310 void addFloats(const float* values, int count) { 311 mWriter.writeInt(count); 312 for (int i = 0; i < count; i++) { 313 mWriter.writeScalar(values[i]); 314 } 315 } 316 317 inline void addPoint(float x, float y) { 318 mWriter.writeScalar(x); 319 mWriter.writeScalar(y); 320 } 321 322 inline void addBounds(float left, float top, float right, float bottom) { 323 mWriter.writeScalar(left); 324 mWriter.writeScalar(top); 325 mWriter.writeScalar(right); 326 mWriter.writeScalar(bottom); 327 } 328 329 inline void addText(const void* text, size_t byteLength) { 330 mWriter.writeInt(byteLength); 331 mWriter.writePad(text, byteLength); 332 } 333 334 inline void addPath(const SkPath* path) { 335 if (mPathHeap == NULL) { 336 mPathHeap = new PathHeap(); 337 } 338 addInt(mPathHeap->append(*path)); 339 } 340 341 int find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint); 342 343 inline void addPaint(const SkPaint* paint) { 344 addInt(find(mPaints, paint)); 345 } 346 347 int find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix); 348 349 inline void addMatrix(const SkMatrix* matrix) { 350 addInt(find(mMatrices, matrix)); 351 } 352 353 int find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap); 354 355 inline void addBitmap(const SkBitmap* bitmap) { 356 addInt(find(mBitmaps, *bitmap)); 357 } 358 359 SkChunkAlloc mHeap; 360 361 int mBitmapIndex; 362 SkTDArray<const SkFlatBitmap*> mBitmaps; 363 364 int mMatrixIndex; 365 SkTDArray<const SkFlatMatrix*> mMatrices; 366 367 int mPaintIndex; 368 SkTDArray<const SkFlatPaint*> mPaints; 369 370 PathHeap* mPathHeap; 371 SkWriter32 mWriter; 372 373 SkRefCntRecorder mRCRecorder; 374 SkRefCntRecorder mTFRecorder; 375 376 friend class DisplayList; 377 378}; // class DisplayListRenderer 379 380}; // namespace uirenderer 381}; // namespace android 382 383#endif // ANDROID_UI_DISPLAY_LIST_RENDERER_H 384