1 // Copyright 2017 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 COMPONENTS_WEBXR_MAILBOX_TO_SURFACE_BRIDGE_IMPL_H_
6 #define COMPONENTS_WEBXR_MAILBOX_TO_SURFACE_BRIDGE_IMPL_H_
7 
8 #include "base/callback.h"
9 #include "base/macros.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/single_thread_task_runner.h"
12 #include "device/vr/android/mailbox_to_surface_bridge.h"
13 #include "gpu/command_buffer/common/sync_token.h"
14 #include "gpu/ipc/common/surface_handle.h"
15 #include "ui/gfx/buffer_format_util.h"
16 #include "ui/gfx/gpu_fence.h"
17 #include "ui/gl/android/scoped_java_surface.h"
18 
19 namespace gpu {
20 class ContextSupport;
21 
22 namespace gles2 {
23 class GLES2Interface;
24 }
25 }  // namespace gpu
26 
27 namespace viz {
28 class ContextProvider;
29 }
30 
31 namespace webxr {
32 
33 class MailboxToSurfaceBridgeImpl : public device::MailboxToSurfaceBridge {
34  public:
35   // It's OK to create an object instance and pass it to a different thread,
36   // i.e. to enable dependency injection for a unit test, but all methods on it
37   // must be called consistently on a single GL thread. This is verified by
38   // DCHECKs.
39   MailboxToSurfaceBridgeImpl();
40   ~MailboxToSurfaceBridgeImpl() override;
41 
42   bool IsConnected() override;
43 
44   bool IsGpuWorkaroundEnabled(int32_t workaround) override;
45 
46   void CreateSurface(gl::SurfaceTexture*) override;
47 
48   void CreateAndBindContextProvider(base::OnceClosure callback) override;
49 
50   // All other public methods below must be called on the GL thread
51   // (except when marked otherwise).
52 
53   void ResizeSurface(int width, int height) override;
54 
55   bool CopyMailboxToSurfaceAndSwap(const gpu::MailboxHolder& mailbox) override;
56 
57   bool CopyMailboxToSurfaceAndSwap(const gpu::MailboxHolder& mailbox,
58                                    const gfx::Transform& uv_transform) override;
59 
60   void GenSyncToken(gpu::SyncToken* out_sync_token) override;
61 
62   void WaitSyncToken(const gpu::SyncToken& sync_token) override;
63 
64   void WaitForClientGpuFence(gfx::GpuFence*) override;
65 
66   void CreateGpuFence(const gpu::SyncToken& sync_token,
67                       base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>
68                           callback) override;
69 
70   gpu::MailboxHolder CreateSharedImage(
71       gpu::GpuMemoryBufferImplAndroidHardwareBuffer* buffer,
72       const gfx::ColorSpace& color_space,
73       uint32_t usage) override;
74 
75   void DestroySharedImage(const gpu::MailboxHolder& mailbox_holder) override;
76 
77  private:
78   void BindContextProviderToCurrentThread();
79   void OnContextAvailableOnUiThread(
80       scoped_refptr<viz::ContextProvider> provider);
81   void InitializeRenderer();
82   void DestroyContext();
83   void DrawQuad(unsigned int textureHandle, const gfx::Transform& uv_transform);
84 
85   scoped_refptr<viz::ContextProvider> context_provider_;
86   std::unique_ptr<gl::ScopedJavaSurface> surface_;
87   gpu::gles2::GLES2Interface* gl_ = nullptr;
88   gpu::ContextSupport* context_support_ = nullptr;
89   int surface_handle_ = gpu::kNullSurfaceHandle;
90   // TODO(https://crbug.com/836524): shouldn't have both of these closures
91   // in the same class like this.
92   base::OnceClosure on_context_bound_;
93 
94   int surface_width_ = 0;
95   int surface_height_ = 0;
96 
97   // If true, surface width/height is the intended size that should be applied
98   // to the surface once it's ready for use.
99   bool needs_resize_ = false;
100 
101   // A swap ID which is passed to GL swap. Incremented each call.
102   uint64_t swap_id_ = 0;
103 
104   // Uniform handle for the UV transform used by DrawQuad.
105   uint32_t uniform_uv_transform_handle_ = 0;
106 
107   // A task runner for the GL thread
108   scoped_refptr<base::SingleThreadTaskRunner> gl_thread_task_runner_;
109 
110   // Must be last.
111   base::WeakPtrFactory<MailboxToSurfaceBridgeImpl> weak_ptr_factory_{this};
112 
113   DISALLOW_COPY_AND_ASSIGN(MailboxToSurfaceBridgeImpl);
114 };
115 
116 class MailboxToSurfaceBridgeFactoryImpl
117     : public device::MailboxToSurfaceBridgeFactory {
118  public:
119   std::unique_ptr<device::MailboxToSurfaceBridge> Create() const override;
120 };
121 
122 }  // namespace webxr
123 
124 #endif  // COMPONENTS_WEBXR_MAILBOX_TO_SURFACE_BRIDGE_H_
125