Home | History | Annotate | Download | only in core
      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 
     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);
     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