1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_CONTEXT_STATE_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_SHARED_CONTEXT_STATE_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "base/memory/memory_pressure_listener.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/observer_list.h"
15 #include "base/trace_event/memory_dump_provider.h"
16 #include "build/build_config.h"
17 #include "gpu/command_buffer/common/skia_utils.h"
18 #include "gpu/command_buffer/service/gl_context_virtual_delegate.h"
19 #include "gpu/command_buffer/service/memory_tracking.h"
20 #include "gpu/config/gpu_preferences.h"
21 #include "gpu/gpu_gles2_export.h"
22 #include "gpu/ipc/common/gpu_peak_memory.h"
23 #include "third_party/skia/include/gpu/GrContext.h"
24 #include "ui/gl/progress_reporter.h"
25 
26 namespace gl {
27 class GLContext;
28 class GLShareGroup;
29 class GLSurface;
30 }  // namespace gl
31 
32 namespace viz {
33 class DawnContextProvider;
34 class MetalContextProvider;
35 class VulkanContextProvider;
36 }  // namespace viz
37 
38 namespace gpu {
39 class GpuDriverBugWorkarounds;
40 class GpuProcessActivityFlags;
41 class ServiceTransferCache;
42 
43 namespace gles2 {
44 class FeatureInfo;
45 struct ContextState;
46 }  // namespace gles2
47 
48 class GPU_GLES2_EXPORT SharedContextState
49     : public base::trace_event::MemoryDumpProvider,
50       public gpu::GLContextVirtualDelegate,
51       public base::RefCounted<SharedContextState>,
52       public GrContextOptions::ShaderErrorHandler {
53  public:
54   // TODO: Refactor code to have seperate constructor for GL and Vulkan and not
55   // initialize/use GL related info for vulkan and vice-versa.
56   SharedContextState(
57       scoped_refptr<gl::GLShareGroup> share_group,
58       scoped_refptr<gl::GLSurface> surface,
59       scoped_refptr<gl::GLContext> context,
60       bool use_virtualized_gl_contexts,
61       base::OnceClosure context_lost_callback,
62       GrContextType gr_context_type = GrContextType::kGL,
63       viz::VulkanContextProvider* vulkan_context_provider = nullptr,
64       viz::MetalContextProvider* metal_context_provider = nullptr,
65       viz::DawnContextProvider* dawn_context_provider = nullptr,
66       base::WeakPtr<gpu::MemoryTracker::Observer> peak_memory_monitor =
67           nullptr);
68 
69   void InitializeGrContext(const GpuPreferences& gpu_preferences,
70                            const GpuDriverBugWorkarounds& workarounds,
71                            GrContextOptions::PersistentCache* cache,
72                            GpuProcessActivityFlags* activity_flags = nullptr,
73                            gl::ProgressReporter* progress_reporter = nullptr);
GrContextIsGL()74   bool GrContextIsGL() const {
75     return gr_context_type_ == GrContextType::kGL;
76   }
GrContextIsVulkan()77   bool GrContextIsVulkan() const {
78     return vk_context_provider_ && gr_context_type_ == GrContextType::kVulkan;
79   }
GrContextIsMetal()80   bool GrContextIsMetal() const {
81     return metal_context_provider_ && gr_context_type_ == GrContextType::kMetal;
82   }
GrContextIsDawn()83   bool GrContextIsDawn() const {
84     return dawn_context_provider_ && gr_context_type_ == GrContextType::kDawn;
85   }
86 
87   bool InitializeGL(const GpuPreferences& gpu_preferences,
88                     scoped_refptr<gles2::FeatureInfo> feature_info);
IsGLInitialized()89   bool IsGLInitialized() const { return !!feature_info_; }
90 
91   bool MakeCurrent(gl::GLSurface* surface, bool needs_gl = false);
92   void ReleaseCurrent(gl::GLSurface* surface);
93   void MarkContextLost();
94   bool IsCurrent(gl::GLSurface* surface);
95 
96   void PurgeMemory(
97       base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
98 
99   void UpdateSkiaOwnedMemorySize();
100   uint64_t GetMemoryUsage();
101 
102   void PessimisticallyResetGrContext() const;
103 
share_group()104   gl::GLShareGroup* share_group() { return share_group_.get(); }
context()105   gl::GLContext* context() { return context_.get(); }
real_context()106   gl::GLContext* real_context() { return real_context_.get(); }
surface()107   gl::GLSurface* surface() { return surface_.get(); }
vk_context_provider()108   viz::VulkanContextProvider* vk_context_provider() {
109     return vk_context_provider_;
110   }
metal_context_provider()111   viz::MetalContextProvider* metal_context_provider() {
112     return metal_context_provider_;
113   }
dawn_context_provider()114   viz::DawnContextProvider* dawn_context_provider() {
115     return dawn_context_provider_;
116   }
progress_reporter()117   gl::ProgressReporter* progress_reporter() const { return progress_reporter_; }
gr_context()118   GrContext* gr_context() { return gr_context_; }
119   // Handles Skia-reported shader compilation errors.
120   void compileError(const char* shader, const char* errors) override;
feature_info()121   gles2::FeatureInfo* feature_info() { return feature_info_.get(); }
context_state()122   gles2::ContextState* context_state() const { return context_state_.get(); }
context_lost()123   bool context_lost() const { return context_lost_; }
need_context_state_reset()124   bool need_context_state_reset() const { return need_context_state_reset_; }
set_need_context_state_reset(bool reset)125   void set_need_context_state_reset(bool reset) {
126     need_context_state_reset_ = reset;
127   }
transfer_cache()128   ServiceTransferCache* transfer_cache() { return transfer_cache_.get(); }
scratch_deserialization_buffer()129   std::vector<uint8_t>* scratch_deserialization_buffer() {
130     return &scratch_deserialization_buffer_;
131   }
use_virtualized_gl_contexts()132   bool use_virtualized_gl_contexts() const {
133     return use_virtualized_gl_contexts_;
134   }
support_vulkan_external_object()135   bool support_vulkan_external_object() const {
136     return support_vulkan_external_object_;
137   }
memory_tracker()138   gpu::MemoryTracker::Observer* memory_tracker() { return &memory_tracker_; }
139 
140   // base::trace_event::MemoryDumpProvider implementation.
141   bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
142                     base::trace_event::ProcessMemoryDump* pmd) override;
143 
144   // Observer class which is notified when the context is lost.
145   class ContextLostObserver {
146    public:
147     virtual void OnContextLost() = 0;
148 
149    protected:
~ContextLostObserver()150     virtual ~ContextLostObserver() {}
151   };
152   void AddContextLostObserver(ContextLostObserver* obs);
153   void RemoveContextLostObserver(ContextLostObserver* obs);
154 
155  private:
156   friend class base::RefCounted<SharedContextState>;
157 
158   // Observer which is notified when SkiaOutputSurfaceImpl takes ownership of a
159   // shared image, and forward information to both histograms and task manager.
160   class GPU_GLES2_EXPORT MemoryTracker : public gpu::MemoryTracker::Observer {
161    public:
162     explicit MemoryTracker(
163         base::WeakPtr<gpu::MemoryTracker::Observer> peak_memory_monitor);
164     MemoryTracker(MemoryTracker&) = delete;
165     MemoryTracker& operator=(MemoryTracker&) = delete;
166     ~MemoryTracker() override;
167 
168     // gpu::MemoryTracker::Observer implementation:
169     void OnMemoryAllocatedChange(
170         CommandBufferId id,
171         uint64_t old_size,
172         uint64_t new_size,
173         GpuPeakMemoryAllocationSource source =
174             GpuPeakMemoryAllocationSource::UNKNOWN) override;
175 
176     // Reports to GpuServiceImpl::GetVideoMemoryUsageStats()
GetMemoryUsage()177     uint64_t GetMemoryUsage() const { return size_; }
178 
179    private:
180     uint64_t size_ = 0;
181     base::WeakPtr<gpu::MemoryTracker::Observer> const peak_memory_monitor_;
182   };
183 
184   ~SharedContextState() override;
185 
186   // gpu::GLContextVirtualDelegate implementation.
187   bool initialized() const override;
188   const gles2::ContextState* GetContextState() override;
189   void RestoreState(const gles2::ContextState* prev_state) override;
190   void RestoreGlobalState() const override;
191   void ClearAllAttributes() const override;
192   void RestoreActiveTexture() const override;
193   void RestoreAllTextureUnitAndSamplerBindings(
194       const gles2::ContextState* prev_state) const override;
195   void RestoreActiveTextureUnitBinding(unsigned int target) const override;
196   void RestoreBufferBinding(unsigned int target) override;
197   void RestoreBufferBindings() const override;
198   void RestoreFramebufferBindings() const override;
199   void RestoreRenderbufferBindings() override;
200   void RestoreProgramBindings() const override;
201   void RestoreTextureUnitBindings(unsigned unit) const override;
202   void RestoreVertexAttribArray(unsigned index) override;
203   void RestoreAllExternalTextureBindingsIfNeeded() override;
204   QueryManager* GetQueryManager() override;
205 
206   bool use_virtualized_gl_contexts_ = false;
207   bool support_vulkan_external_object_ = false;
208   base::OnceClosure context_lost_callback_;
209   GrContextType gr_context_type_ = GrContextType::kGL;
210   MemoryTracker memory_tracker_;
211   viz::VulkanContextProvider* const vk_context_provider_;
212   viz::MetalContextProvider* const metal_context_provider_;
213   viz::DawnContextProvider* const dawn_context_provider_;
214   GrContext* gr_context_ = nullptr;
215 
216   scoped_refptr<gl::GLShareGroup> share_group_;
217   scoped_refptr<gl::GLContext> context_;
218   scoped_refptr<gl::GLContext> real_context_;
219   scoped_refptr<gl::GLSurface> surface_;
220 
221   // Most recent surface that this ShareContextState was made current with.
222   // Avoids a call to MakeCurrent with a different surface, if we don't
223   // care which surface is current.
224   gl::GLSurface* last_current_surface_ = nullptr;
225 
226   scoped_refptr<gles2::FeatureInfo> feature_info_;
227 
228   // raster decoders and display compositor share this context_state_.
229   std::unique_ptr<gles2::ContextState> context_state_;
230 
231   gl::ProgressReporter* progress_reporter_ = nullptr;
232   sk_sp<GrContext> owned_gr_context_;
233   std::unique_ptr<ServiceTransferCache> transfer_cache_;
234   uint64_t skia_gr_cache_size_ = 0;
235   std::vector<uint8_t> scratch_deserialization_buffer_;
236 
237   // |need_context_state_reset| is set whenever Skia may have altered the
238   // driver's GL state.
239   bool need_context_state_reset_ = false;
240 
241   bool context_lost_ = false;
242   base::ObserverList<ContextLostObserver>::Unchecked context_lost_observers_;
243 
244   base::WeakPtrFactory<SharedContextState> weak_ptr_factory_{this};
245 
246   DISALLOW_COPY_AND_ASSIGN(SharedContextState);
247 };
248 
249 }  // namespace gpu
250 
251 #endif  // GPU_COMMAND_BUFFER_SERVICE_SHARED_CONTEXT_STATE_H_
252