| 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 |