OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 APPS_MOTERM_GL_HELPER_H_ | |
6 #define APPS_MOTERM_GL_HELPER_H_ | |
7 | |
8 #include <GLES2/gl2.h> | |
9 #include <MGL/mgl_types.h> | |
10 | |
11 #include <deque> | |
12 #include <vector> | |
13 | |
14 #include "base/macros.h" | |
15 #include "base/memory/weak_ptr.h" | |
16 #include "mojo/public/cpp/bindings/binding.h" | |
17 #include "mojo/services/geometry/interfaces/geometry.mojom.h" | |
18 #include "mojo/services/gpu/interfaces/gpu.mojom.h" | |
19 #include "mojo/services/surfaces/interfaces/surface_id.mojom.h" | |
20 #include "mojo/services/surfaces/interfaces/surfaces.mojom.h" | |
21 | |
22 namespace mojo { | |
23 class Shell; | |
24 } | |
25 | |
26 // A class that helps with drawing surfaces using GL. | |
27 class GlHelper : public mojo::ResourceReturner { | |
28 public: | |
29 class Client { | |
30 public: | |
31 // Called when the surface ID changes (including the first time it becomes | |
32 // available). | |
33 virtual void OnSurfaceIdChanged(mojo::SurfaceIdPtr surface_id) = 0; | |
34 | |
35 // Called when the GL context is lost. | |
36 virtual void OnContextLost() = 0; | |
37 | |
38 // Called when the frame with ID |frame_id| (from |EndFrame()|) is drawn for | |
39 // the first time. Use this to rate-limit draws. | |
40 virtual void OnFrameDisplayed(uint32_t frame_id) = 0; | |
41 }; | |
42 | |
43 // Both |client| and |shell| must outlive us. |texture_format| is the texture | |
44 // format to use, e.g., |GL_RGBA| or |GL_BGRA_EXT|. |flipped| means that the | |
45 // texture is in the usual GL orientation (origin at lower-left). This object | |
46 // will create a surface (of initial size |initial_size|), and call the | |
47 // client's |OnSurfaceIdChanged()| when it has a surface ID for it (which the | |
48 // client can then provide to its |View|). | |
49 GlHelper(Client* client, | |
50 mojo::Shell* shell, | |
51 GLint texture_format, | |
52 bool flipped, | |
53 const mojo::Size& initial_size); | |
54 ~GlHelper() override; | |
55 | |
56 // Sets the size of the surface. (The surface will only be created at this | |
57 // size lazily at the next |StartFrame()|.) | |
58 void SetSurfaceSize(const mojo::Size& surface_size); | |
59 | |
60 // Ensures that a GL context is available and makes it current. (Note that | |
61 // this is automatically called by |StartFrame()|, so this is mostly useful | |
62 // for creating GL resources outside |StartFrame()|/|EndFrame()|. | |
63 void MakeCurrent(); | |
64 | |
65 // Starts a frame; makes an appropriate GL context current, and binds a | |
66 // texture of the current size (creating it if necessary), returning its ID. | |
67 // Between |StartFrame()| and |EndFrame()|, the run loop must not be run and | |
68 // no other methods of this object other than |MakeCurrent()| and | |
69 // |GetFrameTexture()| may be called. This object must not be destroyed after | |
70 // |StartFrame()| before calling |EndFrame()|. | |
71 void StartFrame(); | |
72 // Completes the current frame (started using |StartFrame()|). Before calling | |
73 // this, the frame's texture must be bound and the GL context must be current. | |
74 // (This is the default state after |StartFrame()|, so nothing has to be done | |
75 // unless another texture is bound or another GL context is made current, | |
76 // respectively.) Returns an ID for this frame (which will be given to the | |
77 // client on |OnFrameDisplayed()|). | |
78 uint32_t EndFrame(); | |
79 | |
80 // Gets the texture that will be used for the current frame, e.g., so that it | |
81 // may be (re)bound. Only valid between |StartFrame()| and |EndFrame()|. (Note | |
82 // that this texture is automatically bound by |StartFrame()|, so this is | |
83 // typically only needed if another texture is bound.) | |
84 GLuint GetFrameTexture(); | |
85 | |
86 private: | |
87 struct TextureInfo { | |
88 TextureInfo(uint32_t resource_id, GLuint texture, const mojo::Size& size) | |
89 : resource_id(resource_id), texture(texture), size(size) {} | |
90 | |
91 // Only interesting if it's pending return. | |
92 uint32_t resource_id; | |
93 GLuint texture; | |
94 mojo::Size size; | |
95 }; | |
96 | |
97 // |mojo::ResourceReturner|: | |
98 void ReturnResources( | |
99 mojo::Array<mojo::ReturnedResourcePtr> resources) override; | |
100 | |
101 // Ensures that we have a GL context and that it is current. | |
102 void EnsureContext(); | |
103 | |
104 // Ensures that we have a surface of the appropriate size. This should only be | |
105 // called with a valid GL context which is current (e.g., after calling | |
106 // |EnsureContext()|). | |
107 void EnsureSurface(); | |
108 | |
109 // Calls the client's |OnSurfaceIdChanged()| if appropriate (both | |
110 // |id_namespace_| and |local_id_| must be set). | |
111 void CallOnSurfaceIdChanged(); | |
112 | |
113 // Texture queue functions. (For all functions, |mgl_context_| should be | |
114 // current.) | |
115 // Gets and binds a texture of size |current_surface_size_|. | |
116 TextureInfo GetTexture(); | |
117 // Returns a texture to the queue (or deletes it, if it's not of the right | |
118 // size or there are already enough textures in the queue). | |
119 void ReturnTexture(const TextureInfo& texture_info); | |
120 // Clears all textures (i.e., calls |glDeleteTextures()| on all textures in | |
121 // the texture queue). | |
122 void ClearTextures(); | |
123 | |
124 // Callbacks: | |
125 | |
126 // Callback for |GetIdNamespace()|: | |
127 void GetIdNamespaceCallback(uint32_t id_namespace); | |
128 | |
129 // "Callback" for |MojoGLES2CreateContext()|: | |
130 static void OnContextLostThunk(void* self); | |
131 void OnContextLost(); | |
132 | |
133 // Callback for |SubmitFrame()|: | |
134 void SubmitFrameCallback(uint32_t frame_id); | |
135 | |
136 Client* const client_; | |
137 const GLint texture_format_; | |
138 const bool flipped_; | |
139 | |
140 mojo::GpuPtr gpu_; | |
141 mojo::SurfacePtr surface_; | |
142 mojo::Binding<mojo::ResourceReturner> returner_binding_; | |
143 | |
144 // The size for the surface at the next |StartFrame()|. | |
145 mojo::Size next_surface_size_; | |
146 | |
147 MGLContext mgl_context_; | |
148 | |
149 std::deque<TextureInfo> textures_; | |
150 | |
151 uint32_t next_frame_id_; | |
152 // The texture that'll be used to draw the current frame. Only valid (nonzero) | |
153 // between |StartFrame()| and |EndFrame()|. | |
154 GLuint frame_texture_; | |
155 | |
156 uint32_t id_namespace_; | |
157 uint32_t local_id_; | |
158 // If |local_id_| is nonzero, there's currently a surface, in which case this | |
159 // is its size. | |
160 mojo::Size current_surface_size_; | |
161 | |
162 uint32_t next_resource_id_; | |
163 std::vector<TextureInfo> textures_pending_return_; | |
164 | |
165 base::WeakPtrFactory<GlHelper> weak_factory_; | |
166 | |
167 DISALLOW_COPY_AND_ASSIGN(GlHelper); | |
168 }; | |
169 | |
170 #endif // APPS_MOTERM_GL_HELPER_H_ | |
OLD | NEW |