• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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