OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gl/gl_surface.h" | 5 #include "ui/gl/gl_surface.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/message_loop/message_loop.h" | |
14 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
15 #include "ui/gfx/native_widget_types.h" | 14 #include "ui/gfx/native_widget_types.h" |
16 #include "ui/gfx/x/x11_types.h" | |
17 #include "ui/gl/gl_bindings.h" | 15 #include "ui/gl/gl_bindings.h" |
18 #include "ui/gl/gl_implementation.h" | 16 #include "ui/gl/gl_implementation.h" |
19 #include "ui/gl/gl_surface_egl.h" | 17 #include "ui/gl/gl_surface_egl.h" |
20 #include "ui/gl/gl_surface_egl_x11.h" | 18 #include "ui/gl/gl_surface_egl_x11.h" |
21 #include "ui/gl/gl_surface_glx.h" | 19 #include "ui/gl/gl_surface_glx.h" |
22 #include "ui/gl/gl_surface_osmesa.h" | 20 #include "ui/gl/gl_surface_osmesa_x11.h" |
23 #include "ui/gl/gl_surface_stub.h" | 21 #include "ui/gl/gl_surface_stub.h" |
24 | 22 |
25 namespace gl { | 23 namespace gl { |
26 | 24 |
27 namespace { | 25 namespace { |
28 | 26 |
29 // This OSMesa GL surface can use XLib to swap the contents of the buffer to a | |
30 // view. | |
31 class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa { | |
32 public: | |
33 explicit NativeViewGLSurfaceOSMesa(gfx::AcceleratedWidget window); | |
34 | |
35 static bool InitializeOneOff(); | |
36 | |
37 // Implement a subset of GLSurface. | |
38 bool Initialize(GLSurface::Format format) override; | |
39 void Destroy() override; | |
40 bool Resize(const gfx::Size& new_size, | |
41 float scale_factor, | |
42 bool alpha) override; | |
43 bool IsOffscreen() override; | |
44 gfx::SwapResult SwapBuffers() override; | |
45 bool SupportsPostSubBuffer() override; | |
46 gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override; | |
47 | |
48 protected: | |
49 ~NativeViewGLSurfaceOSMesa() override; | |
50 | |
51 private: | |
52 Display* xdisplay_; | |
53 GC window_graphics_context_; | |
54 gfx::AcceleratedWidget window_; | |
55 GC pixmap_graphics_context_; | |
56 Pixmap pixmap_; | |
57 | |
58 DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa); | |
59 }; | |
60 | |
61 NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa( | |
62 gfx::AcceleratedWidget window) | |
63 : GLSurfaceOSMesa(SURFACE_OSMESA_BGRA, gfx::Size(1, 1)), | |
64 xdisplay_(gfx::GetXDisplay()), | |
65 window_graphics_context_(0), | |
66 window_(window), | |
67 pixmap_graphics_context_(0), | |
68 pixmap_(0) { | |
69 DCHECK(xdisplay_); | |
70 DCHECK(window_); | |
71 } | |
72 | |
73 // static | |
74 bool NativeViewGLSurfaceOSMesa::InitializeOneOff() { | |
75 static bool initialized = false; | |
76 if (initialized) | |
77 return true; | |
78 | |
79 if (!gfx::GetXDisplay()) { | |
80 LOG(ERROR) << "XOpenDisplay failed."; | |
81 return false; | |
82 } | |
83 | |
84 initialized = true; | |
85 return true; | |
86 } | |
87 | |
88 bool NativeViewGLSurfaceOSMesa::Initialize(GLSurface::Format format) { | |
89 if (!GLSurfaceOSMesa::Initialize(format)) | |
90 return false; | |
91 | |
92 window_graphics_context_ = XCreateGC(xdisplay_, window_, 0, NULL); | |
93 if (!window_graphics_context_) { | |
94 LOG(ERROR) << "XCreateGC failed."; | |
95 Destroy(); | |
96 return false; | |
97 } | |
98 | |
99 return true; | |
100 } | |
101 | |
102 void NativeViewGLSurfaceOSMesa::Destroy() { | |
103 if (pixmap_graphics_context_) { | |
104 XFreeGC(xdisplay_, pixmap_graphics_context_); | |
105 pixmap_graphics_context_ = NULL; | |
106 } | |
107 | |
108 if (pixmap_) { | |
109 XFreePixmap(xdisplay_, pixmap_); | |
110 pixmap_ = 0; | |
111 } | |
112 | |
113 if (window_graphics_context_) { | |
114 XFreeGC(xdisplay_, window_graphics_context_); | |
115 window_graphics_context_ = NULL; | |
116 } | |
117 | |
118 XSync(xdisplay_, False); | |
119 } | |
120 | |
121 bool NativeViewGLSurfaceOSMesa::Resize(const gfx::Size& new_size, | |
122 float scale_factor, | |
123 bool alpha) { | |
124 if (!GLSurfaceOSMesa::Resize(new_size, scale_factor, alpha)) | |
125 return false; | |
126 | |
127 XWindowAttributes attributes; | |
128 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { | |
129 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | |
130 return false; | |
131 } | |
132 | |
133 // Destroy the previous pixmap and graphics context. | |
134 if (pixmap_graphics_context_) { | |
135 XFreeGC(xdisplay_, pixmap_graphics_context_); | |
136 pixmap_graphics_context_ = NULL; | |
137 } | |
138 if (pixmap_) { | |
139 XFreePixmap(xdisplay_, pixmap_); | |
140 pixmap_ = 0; | |
141 } | |
142 | |
143 // Recreate a pixmap to hold the frame. | |
144 pixmap_ = XCreatePixmap(xdisplay_, | |
145 window_, | |
146 new_size.width(), | |
147 new_size.height(), | |
148 attributes.depth); | |
149 if (!pixmap_) { | |
150 LOG(ERROR) << "XCreatePixmap failed."; | |
151 return false; | |
152 } | |
153 | |
154 // Recreate a graphics context for the pixmap. | |
155 pixmap_graphics_context_ = XCreateGC(xdisplay_, pixmap_, 0, NULL); | |
156 if (!pixmap_graphics_context_) { | |
157 LOG(ERROR) << "XCreateGC failed"; | |
158 return false; | |
159 } | |
160 | |
161 return true; | |
162 } | |
163 | |
164 bool NativeViewGLSurfaceOSMesa::IsOffscreen() { | |
165 return false; | |
166 } | |
167 | |
168 gfx::SwapResult NativeViewGLSurfaceOSMesa::SwapBuffers() { | |
169 TRACE_EVENT2("gpu", "NativeViewGLSurfaceOSMesa:RealSwapBuffers", | |
170 "width", GetSize().width(), | |
171 "height", GetSize().height()); | |
172 | |
173 gfx::Size size = GetSize(); | |
174 | |
175 XWindowAttributes attributes; | |
176 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { | |
177 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | |
178 return gfx::SwapResult::SWAP_FAILED; | |
179 } | |
180 | |
181 // Copy the frame into the pixmap. | |
182 gfx::PutARGBImage(xdisplay_, attributes.visual, attributes.depth, pixmap_, | |
183 pixmap_graphics_context_, | |
184 static_cast<const uint8_t*>(GetHandle()), size.width(), | |
185 size.height()); | |
186 | |
187 // Copy the pixmap to the window. | |
188 XCopyArea(xdisplay_, | |
189 pixmap_, | |
190 window_, | |
191 window_graphics_context_, | |
192 0, | |
193 0, | |
194 size.width(), | |
195 size.height(), | |
196 0, | |
197 0); | |
198 | |
199 return gfx::SwapResult::SWAP_ACK; | |
200 } | |
201 | |
202 bool NativeViewGLSurfaceOSMesa::SupportsPostSubBuffer() { | |
203 return true; | |
204 } | |
205 | |
206 gfx::SwapResult NativeViewGLSurfaceOSMesa::PostSubBuffer(int x, | |
207 int y, | |
208 int width, | |
209 int height) { | |
210 gfx::Size size = GetSize(); | |
211 | |
212 // Move (0,0) from lower-left to upper-left | |
213 y = size.height() - y - height; | |
214 | |
215 XWindowAttributes attributes; | |
216 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { | |
217 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | |
218 return gfx::SwapResult::SWAP_FAILED; | |
219 } | |
220 | |
221 // Copy the frame into the pixmap. | |
222 gfx::PutARGBImage(xdisplay_, attributes.visual, attributes.depth, pixmap_, | |
223 pixmap_graphics_context_, | |
224 static_cast<const uint8_t*>(GetHandle()), size.width(), | |
225 size.height(), x, y, x, y, width, height); | |
226 | |
227 // Copy the pixmap to the window. | |
228 XCopyArea(xdisplay_, | |
229 pixmap_, | |
230 window_, | |
231 window_graphics_context_, | |
232 x, | |
233 y, | |
234 width, | |
235 height, | |
236 x, | |
237 y); | |
238 | |
239 return gfx::SwapResult::SWAP_ACK; | |
240 } | |
241 | |
242 NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() { | |
243 Destroy(); | |
244 } | |
245 | |
246 } // namespace | 27 } // namespace |
247 | 28 |
248 bool GLSurface::InitializeOneOffInternal() { | 29 bool GLSurface::InitializeOneOffInternal() { |
249 switch (GetGLImplementation()) { | 30 switch (GetGLImplementation()) { |
250 case kGLImplementationDesktopGL: | 31 case kGLImplementationDesktopGL: |
251 if (!GLSurfaceGLX::InitializeOneOff()) { | 32 if (!GLSurfaceGLX::InitializeOneOff()) { |
252 LOG(ERROR) << "GLSurfaceGLX::InitializeOneOff failed."; | 33 LOG(ERROR) << "GLSurfaceGLX::InitializeOneOff failed."; |
253 return false; | 34 return false; |
254 } | 35 } |
255 break; | 36 break; |
256 case kGLImplementationOSMesaGL: | 37 case kGLImplementationOSMesaGL: |
257 if (!NativeViewGLSurfaceOSMesa::InitializeOneOff()) { | 38 if (!GLSurfaceOSMesaX11::InitializeOneOff()) { |
258 LOG(ERROR) << "NativeViewGLSurfaceOSMesa::InitializeOneOff failed."; | 39 LOG(ERROR) << "GLSurfaceOSMesaX11::InitializeOneOff failed."; |
259 return false; | 40 return false; |
260 } | 41 } |
261 break; | 42 break; |
262 case kGLImplementationEGLGLES2: | 43 case kGLImplementationEGLGLES2: |
263 if (!GLSurfaceEGL::InitializeOneOff()) { | 44 if (!GLSurfaceEGL::InitializeOneOff()) { |
264 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; | 45 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; |
265 return false; | 46 return false; |
266 } | 47 } |
267 break; | 48 break; |
268 default: | 49 default: |
269 break; | 50 break; |
270 } | 51 } |
271 | 52 |
272 return true; | 53 return true; |
273 } | 54 } |
274 | 55 |
275 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( | 56 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( |
276 gfx::AcceleratedWidget window) { | 57 gfx::AcceleratedWidget window) { |
277 TRACE_EVENT0("gpu", "GLSurface::CreateViewGLSurface"); | 58 TRACE_EVENT0("gpu", "GLSurface::CreateViewGLSurface"); |
278 switch (GetGLImplementation()) { | 59 switch (GetGLImplementation()) { |
279 case kGLImplementationOSMesaGL: { | 60 case kGLImplementationOSMesaGL: { |
280 scoped_refptr<GLSurface> surface( | 61 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaX11(window)); |
281 new NativeViewGLSurfaceOSMesa(window)); | |
282 if (!surface->Initialize()) | 62 if (!surface->Initialize()) |
283 return NULL; | 63 return NULL; |
284 | 64 |
285 return surface; | 65 return surface; |
286 } | 66 } |
287 case kGLImplementationDesktopGL: { | 67 case kGLImplementationDesktopGL: { |
288 scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceGLX(window)); | 68 scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceGLX(window)); |
289 if (!surface->Initialize()) | 69 if (!surface->Initialize()) |
290 return NULL; | 70 return NULL; |
291 | 71 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 NOTREACHED(); | 120 NOTREACHED(); |
341 return NULL; | 121 return NULL; |
342 } | 122 } |
343 } | 123 } |
344 | 124 |
345 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { | 125 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { |
346 return gfx::GetXDisplay(); | 126 return gfx::GetXDisplay(); |
347 } | 127 } |
348 | 128 |
349 } // namespace gl | 129 } // namespace gl |
OLD | NEW |