1 /* 2 * Copyright 2021 Google LLC 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 skgpu_Recorder_DEFINED 9 #define skgpu_Recorder_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/private/SingleOwner.h" 13 14 #include <vector> 15 16 namespace skgpu { 17 18 class Caps; 19 class Device; 20 class DrawBufferManager; 21 class GlobalCache; 22 class Gpu; 23 class RecorderPriv; 24 class Recording; 25 class ResourceProvider; 26 class Task; 27 class TaskGraph; 28 class UniformCache; 29 30 class Recorder final { 31 public: 32 Recorder(const Recorder&) = delete; 33 Recorder(Recorder&&) = delete; 34 Recorder& operator=(const Recorder&) = delete; 35 Recorder& operator=(Recorder&&) = delete; 36 37 ~Recorder(); 38 39 std::unique_ptr<Recording> snap(); 40 41 // Provides access to functions that aren't part of the public API. 42 RecorderPriv priv(); 43 const RecorderPriv priv() const; // NOLINT(readability-const-return-type) 44 45 #if GR_TEST_UTILS 46 bool deviceIsRegistered(Device*); 47 #endif 48 49 private: 50 friend class Context; // For ctor 51 friend class Device; // For registering and deregistering Devices; 52 friend class RecorderPriv; // for ctor and hidden methods 53 54 Recorder(sk_sp<Gpu>, sk_sp<GlobalCache>); 55 singleOwner()56 SingleOwner* singleOwner() const { return &fSingleOwner; } 57 58 // We keep track of all Devices that are connected to a Recorder. This allows the client to 59 // safely delete an SkSurface or a Recorder in any order. If the client deletes the Recorder 60 // we need to notify all Devices that the Recorder is no longer valid. If we delete the 61 // SkSurface/Device first we will flush all the Device's into the Recorder before deregistering 62 // it from the Recorder. 63 // 64 // We do not need to take a ref on the Device since the Device will flush and deregister itself 65 // in its dtor. There is no other need for the Recorder to know about the Device after this 66 // point. 67 // 68 // Note: We could probably get by with only registering Devices directly connected to 69 // SkSurfaces. All other one off Devices will be created in a controlled scope where the 70 // Recorder should still be valid by the time they need to flush their work when the Device is 71 // deleted. We would have to make sure we safely handle cases where a client calls saveLayer 72 // then either deletes the SkSurface or Recorder before calling restore. For simplicity we just 73 // register every device for now, but if we see extra overhead in pushing back the extra 74 // pointers, we can look into only registering SkSurface Devices. 75 void registerDevice(Device*); 76 void deregisterDevice(const Device*); 77 78 sk_sp<Gpu> fGpu; 79 std::unique_ptr<ResourceProvider> fResourceProvider; 80 81 std::unique_ptr<TaskGraph> fGraph; 82 std::unique_ptr<UniformCache> fUniformCache; 83 std::unique_ptr<DrawBufferManager> fDrawBufferManager; 84 std::vector<Device*> fTrackedDevices; 85 86 // In debug builds we guard against improper thread handling 87 // This guard is passed to the ResourceCache. 88 // TODO: Should we also pass this to Device, DrawContext, and similar classes? 89 mutable SingleOwner fSingleOwner; 90 }; 91 92 } // namespace skgpu 93 94 #endif // skgpu_Recorder_DEFINED 95