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