1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkThreadedBMPDevice_DEFINED 9 #define SkThreadedBMPDevice_DEFINED 10 11 #include "SkDraw.h" 12 #include "SkBitmapDevice.h" 13 14 #include <future> 15 16 class TiledDrawScheduler { 17 public: 18 using WorkFunc = std::function<void(int, int)>; 19 ~TiledDrawScheduler()20 virtual ~TiledDrawScheduler() {} 21 22 virtual void signal() = 0; // signal that one more draw is available for all tiles 23 24 // Tell scheduler that no more draw calls will be added (no signal will be called). 25 virtual void finish() = 0; 26 27 // Handle the next draw available. This method will block until 28 // (1) the next draw is finished, or 29 // (2) the finish is called 30 // The method will return true for case (1) and false for case (2). 31 // When there's no draw available and we haven't called finish, we will just wait. 32 // In many cases, the parameter tileIndex specifies the tile that the next draw should happen. 33 // However, for some schedulers, that tileIndex may only be a hint and the scheduler is free 34 // to find another tile to draw. In that case, tileIndex will be changed to the actual tileIndex 35 // where the draw happens. 36 virtual bool next(int& tileIndex) = 0; 37 }; 38 39 /////////////////////////////////////////////////////////////////////////////// 40 class SkThreadedBMPDevice : public SkBitmapDevice { 41 public: 42 // When threads = 0, we make fThreadCnt = fTileCnt 43 SkThreadedBMPDevice(const SkBitmap& bitmap, int tiles, int threads = 0); ~SkThreadedBMPDevice()44 ~SkThreadedBMPDevice() override { finishThreads(); } 45 46 protected: 47 void drawPaint(const SkPaint& paint) override; 48 void drawPoints(SkCanvas::PointMode mode, size_t count, 49 const SkPoint[], const SkPaint& paint) override; 50 void drawRect(const SkRect& r, const SkPaint& paint) override; 51 void drawRRect(const SkRRect& rr, const SkPaint& paint) override; 52 53 void drawPath(const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix, 54 bool pathIsMutable) override; 55 void drawBitmap(const SkBitmap&, SkScalar x, SkScalar y, const SkPaint&) override; 56 void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) override; 57 58 void drawText(const void* text, size_t len, SkScalar x, SkScalar y, 59 const SkPaint&) override; 60 void drawPosText(const void* text, size_t len, const SkScalar pos[], 61 int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override; 62 void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override; 63 void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override; 64 65 void flush() override; 66 67 private: 68 struct DrawElement { 69 SkIRect fDrawBounds; 70 std::function<void(const SkIRect& threadBounds)> fDrawFn; 71 }; 72 73 struct DrawState; 74 75 SkIRect transformDrawBounds(const SkRect& drawBounds) const; 76 77 void startThreads(); 78 void finishThreads(); 79 80 static constexpr int MAX_QUEUE_SIZE = 100000; 81 82 const int fTileCnt; 83 const int fThreadCnt; 84 std::unique_ptr<TiledDrawScheduler> fScheduler; 85 SkTArray<SkIRect> fTileBounds; 86 SkTArray<std::future<void>> fThreadFutures; 87 DrawElement fQueue[MAX_QUEUE_SIZE]; 88 int fQueueSize; 89 90 typedef SkBitmapDevice INHERITED; 91 }; 92 93 #endif // SkThreadedBMPDevice_DEFINED 94