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 <SkMatrix.h> 21 #include <SkPaint.h> 22 #include <SkPath.h> 23 #include <cutils/compiler.h> 24 25 #include "DisplayListLogBuffer.h" 26 #include "RenderNode.h" 27 28 namespace android { 29 namespace uirenderer { 30 31 /////////////////////////////////////////////////////////////////////////////// 32 // Defines 33 /////////////////////////////////////////////////////////////////////////////// 34 35 // Debug 36 #if DEBUG_DISPLAY_LIST 37 #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__) 38 #else 39 #define DISPLAY_LIST_LOGD(...) 40 #endif 41 42 /////////////////////////////////////////////////////////////////////////////// 43 // Display list 44 /////////////////////////////////////////////////////////////////////////////// 45 46 class DeferredDisplayList; 47 class DisplayListRenderer; 48 class DisplayListOp; 49 class DrawOp; 50 class StateOp; 51 52 /** 53 * Records drawing commands in a display list for later playback into an OpenGLRenderer. 54 */ 55 class ANDROID_API DisplayListRenderer: public StatefulBaseRenderer { 56 public: 57 DisplayListRenderer(); 58 virtual ~DisplayListRenderer(); 59 60 void insertReorderBarrier(bool enableReorder); 61 62 DisplayListData* finishRecording(); 63 64 // ---------------------------------------------------------------------------- 65 // Frame state operations 66 // ---------------------------------------------------------------------------- 67 virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); 68 virtual void finish(); 69 virtual void interrupt(); 70 virtual void resume(); 71 72 // ---------------------------------------------------------------------------- 73 // Canvas state operations 74 // ---------------------------------------------------------------------------- 75 // Save (layer) 76 virtual int save(int flags); 77 virtual void restore(); 78 virtual void restoreToCount(int saveCount); 79 virtual int saveLayer(float left, float top, float right, float bottom, 80 const SkPaint* paint, int flags); 81 82 // Matrix 83 virtual void translate(float dx, float dy, float dz = 0.0f); 84 virtual void rotate(float degrees); 85 virtual void scale(float sx, float sy); 86 virtual void skew(float sx, float sy); 87 88 virtual void setMatrix(const SkMatrix& matrix); 89 virtual void concatMatrix(const SkMatrix& matrix); 90 91 // Clip 92 virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 93 virtual bool clipPath(const SkPath* path, SkRegion::Op op); 94 virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); 95 96 // Misc - should be implemented with SkPaint inspection 97 virtual void resetPaintFilter(); 98 virtual void setupPaintFilter(int clearBits, int setBits); 99 100 bool isCurrentTransformSimple() { 101 return currentTransform()->isSimple(); 102 } 103 104 // ---------------------------------------------------------------------------- 105 // Canvas draw operations 106 // ---------------------------------------------------------------------------- 107 virtual status_t drawColor(int color, SkXfermode::Mode mode); 108 109 // Bitmap-based 110 virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); 111 virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, 112 float srcRight, float srcBottom, float dstLeft, float dstTop, 113 float dstRight, float dstBottom, const SkPaint* paint); 114 virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); 115 virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, 116 const float* vertices, const int* colors, const SkPaint* paint); 117 virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, 118 float left, float top, float right, float bottom, const SkPaint* paint); 119 120 // Shapes 121 virtual status_t drawRect(float left, float top, float right, float bottom, 122 const SkPaint* paint); 123 virtual status_t drawRects(const float* rects, int count, const SkPaint* paint); 124 virtual status_t drawRoundRect(float left, float top, float right, float bottom, 125 float rx, float ry, const SkPaint* paint); 126 virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, 127 CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, 128 CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, 129 CanvasPropertyPaint* paint); 130 virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint); 131 virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, 132 CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint); 133 virtual status_t drawOval(float left, float top, float right, float bottom, 134 const SkPaint* paint); 135 virtual status_t drawArc(float left, float top, float right, float bottom, 136 float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint); 137 virtual status_t drawPath(const SkPath* path, const SkPaint* paint); 138 virtual status_t drawLines(const float* points, int count, const SkPaint* paint); 139 virtual status_t drawPoints(const float* points, int count, const SkPaint* paint); 140 141 // Text 142 virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, 143 const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, 144 DrawOpMode drawOpMode = kDrawOpMode_Immediate); 145 virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, 146 float hOffset, float vOffset, const SkPaint* paint); 147 virtual status_t drawPosText(const char* text, int bytesCount, int count, 148 const float* positions, const SkPaint* paint); 149 150 // ---------------------------------------------------------------------------- 151 // Canvas draw operations - special 152 // ---------------------------------------------------------------------------- 153 virtual status_t drawLayer(Layer* layer, float x, float y); 154 virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags); 155 156 // TODO: rename for consistency 157 virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); 158 159 void setHighContrastText(bool highContrastText) { 160 mHighContrastText = highContrastText; 161 } 162 private: 163 enum DeferredBarrierType { 164 kBarrier_None, 165 kBarrier_InOrder, 166 kBarrier_OutOfOrder, 167 }; 168 169 void flushRestoreToCount(); 170 void flushTranslate(); 171 void flushReorderBarrier(); 172 173 LinearAllocator& alloc() { return mDisplayListData->allocator; } 174 175 // Each method returns final index of op 176 size_t addOpAndUpdateChunk(DisplayListOp* op); 177 // flushes any deferred operations, and appends the op 178 size_t flushAndAddOp(DisplayListOp* op); 179 180 size_t addStateOp(StateOp* op); 181 size_t addDrawOp(DrawOp* op); 182 size_t addRenderNodeOp(DrawRenderNodeOp* op); 183 184 185 template<class T> 186 inline const T* refBuffer(const T* srcBuffer, int32_t count) { 187 if (!srcBuffer) return NULL; 188 189 T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T)); 190 memcpy(dstBuffer, srcBuffer, count * sizeof(T)); 191 return dstBuffer; 192 } 193 194 inline char* refText(const char* text, size_t byteLength) { 195 return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength); 196 } 197 198 inline const SkPath* refPath(const SkPath* path) { 199 if (!path) return NULL; 200 201 const SkPath* pathCopy = mPathMap.valueFor(path); 202 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 203 SkPath* newPathCopy = new SkPath(*path); 204 newPathCopy->setSourcePath(path); 205 206 pathCopy = newPathCopy; 207 // replaceValueFor() performs an add if the entry doesn't exist 208 mPathMap.replaceValueFor(path, pathCopy); 209 mDisplayListData->paths.add(pathCopy); 210 } 211 if (mDisplayListData->sourcePaths.indexOf(path) < 0) { 212 mCaches.resourceCache.incrementRefcount(path); 213 mDisplayListData->sourcePaths.add(path); 214 } 215 return pathCopy; 216 } 217 218 inline const SkPaint* refPaint(const SkPaint* paint) { 219 if (!paint) return NULL; 220 221 const SkPaint* paintCopy = mPaintMap.valueFor(paint); 222 if (paintCopy == NULL 223 || paintCopy->getGenerationID() != paint->getGenerationID() 224 // We can't compare shader pointers because that will always 225 // change as we do partial copying via wrapping. However, if the 226 // shader changes the paint generationID will have changed and 227 // so we don't hit this comparison anyway 228 || !(paint->getShader() && paintCopy->getShader() 229 && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) { 230 paintCopy = copyPaint(paint); 231 // replaceValueFor() performs an add if the entry doesn't exist 232 mPaintMap.replaceValueFor(paint, paintCopy); 233 } 234 235 return paintCopy; 236 } 237 238 inline SkPaint* copyPaint(const SkPaint* paint) { 239 if (!paint) return NULL; 240 SkPaint* paintCopy = new SkPaint(*paint); 241 if (paint->getShader()) { 242 SkShader* shaderCopy = SkShader::CreateLocalMatrixShader( 243 paint->getShader(), paint->getShader()->getLocalMatrix()); 244 paintCopy->setShader(shaderCopy); 245 paintCopy->setGenerationID(paint->getGenerationID()); 246 shaderCopy->setGenerationID(paint->getShader()->getGenerationID()); 247 shaderCopy->unref(); 248 } 249 mDisplayListData->paints.add(paintCopy); 250 return paintCopy; 251 } 252 253 inline const SkRegion* refRegion(const SkRegion* region) { 254 if (!region) { 255 return region; 256 } 257 258 const SkRegion* regionCopy = mRegionMap.valueFor(region); 259 // TODO: Add generation ID to SkRegion 260 if (regionCopy == NULL) { 261 regionCopy = new SkRegion(*region); 262 // replaceValueFor() performs an add if the entry doesn't exist 263 mRegionMap.replaceValueFor(region, regionCopy); 264 mDisplayListData->regions.add(regionCopy); 265 } 266 267 return regionCopy; 268 } 269 270 inline Layer* refLayer(Layer* layer) { 271 mDisplayListData->layers.add(layer); 272 mCaches.resourceCache.incrementRefcount(layer); 273 return layer; 274 } 275 276 inline const SkBitmap* refBitmap(const SkBitmap* bitmap) { 277 // Note that this assumes the bitmap is immutable. There are cases this won't handle 278 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 279 // contents, and drawing again. The only fix would be to always copy it the first time, 280 // which doesn't seem worth the extra cycles for this unlikely case. 281 mDisplayListData->bitmapResources.add(bitmap); 282 mCaches.resourceCache.incrementRefcount(bitmap); 283 return bitmap; 284 } 285 286 inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) { 287 mDisplayListData->ownedBitmapResources.add(bitmap); 288 mCaches.resourceCache.incrementRefcount(bitmap); 289 return bitmap; 290 } 291 292 inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) { 293 mDisplayListData->patchResources.add(patch); 294 mCaches.resourceCache.incrementRefcount(patch); 295 return patch; 296 } 297 298 DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap; 299 DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap; 300 DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap; 301 302 Caches& mCaches; 303 DisplayListData* mDisplayListData; 304 305 float mTranslateX; 306 float mTranslateY; 307 bool mHasDeferredTranslate; 308 DeferredBarrierType mDeferredBarrierType; 309 bool mHighContrastText; 310 311 int mRestoreSaveCount; 312 313 friend class RenderNode; 314 315 }; // class DisplayListRenderer 316 317 }; // namespace uirenderer 318 }; // namespace android 319 320 #endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 321