Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / ui / gl / gl_surface_x11.cc
bloba5d5aab781257066d466c4a66aa91e3663a60758
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
3 // found in the LICENSE file.
5 #include "ui/gl/gl_surface.h"
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "third_party/mesa/src/include/GL/osmesa.h"
12 #include "ui/gfx/native_widget_types.h"
13 #include "ui/gfx/x/x11_types.h"
14 #include "ui/gl/gl_bindings.h"
15 #include "ui/gl/gl_implementation.h"
16 #include "ui/gl/gl_surface_egl.h"
17 #include "ui/gl/gl_surface_glx.h"
18 #include "ui/gl/gl_surface_osmesa.h"
19 #include "ui/gl/gl_surface_stub.h"
21 namespace gfx {
23 // This OSMesa GL surface can use XLib to swap the contents of the buffer to a
24 // view.
25 class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
26 public:
27 explicit NativeViewGLSurfaceOSMesa(gfx::AcceleratedWidget window);
29 static bool InitializeOneOff();
31 // Implement a subset of GLSurface.
32 virtual bool Initialize() OVERRIDE;
33 virtual void Destroy() OVERRIDE;
34 virtual bool Resize(const gfx::Size& new_size) OVERRIDE;
35 virtual bool IsOffscreen() OVERRIDE;
36 virtual bool SwapBuffers() OVERRIDE;
37 virtual bool SupportsPostSubBuffer() OVERRIDE;
38 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE;
40 protected:
41 virtual ~NativeViewGLSurfaceOSMesa();
43 private:
44 Display* xdisplay_;
45 GC window_graphics_context_;
46 gfx::AcceleratedWidget window_;
47 GC pixmap_graphics_context_;
48 Pixmap pixmap_;
50 DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa);
53 bool GLSurface::InitializeOneOffInternal() {
54 switch (GetGLImplementation()) {
55 case kGLImplementationDesktopGL:
56 if (!GLSurfaceGLX::InitializeOneOff()) {
57 LOG(ERROR) << "GLSurfaceGLX::InitializeOneOff failed.";
58 return false;
60 break;
61 case kGLImplementationOSMesaGL:
62 if (!NativeViewGLSurfaceOSMesa::InitializeOneOff()) {
63 LOG(ERROR) << "NativeViewGLSurfaceOSMesa::InitializeOneOff failed.";
64 return false;
66 break;
67 case kGLImplementationEGLGLES2:
68 if (!GLSurfaceEGL::InitializeOneOff()) {
69 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
70 return false;
72 break;
73 default:
74 break;
77 return true;
80 NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa(
81 gfx::AcceleratedWidget window)
82 : GLSurfaceOSMesa(OSMESA_BGRA, gfx::Size(1, 1)),
83 xdisplay_(gfx::GetXDisplay()),
84 window_graphics_context_(0),
85 window_(window),
86 pixmap_graphics_context_(0),
87 pixmap_(0) {
88 DCHECK(xdisplay_);
89 DCHECK(window_);
92 // static
93 bool NativeViewGLSurfaceOSMesa::InitializeOneOff() {
94 static bool initialized = false;
95 if (initialized)
96 return true;
98 if (!gfx::GetXDisplay()) {
99 LOG(ERROR) << "XOpenDisplay failed.";
100 return false;
103 initialized = true;
104 return true;
107 bool NativeViewGLSurfaceOSMesa::Initialize() {
108 if (!GLSurfaceOSMesa::Initialize())
109 return false;
111 window_graphics_context_ = XCreateGC(xdisplay_, window_, 0, NULL);
112 if (!window_graphics_context_) {
113 LOG(ERROR) << "XCreateGC failed.";
114 Destroy();
115 return false;
118 return true;
121 void NativeViewGLSurfaceOSMesa::Destroy() {
122 if (pixmap_graphics_context_) {
123 XFreeGC(xdisplay_, pixmap_graphics_context_);
124 pixmap_graphics_context_ = NULL;
127 if (pixmap_) {
128 XFreePixmap(xdisplay_, pixmap_);
129 pixmap_ = 0;
132 if (window_graphics_context_) {
133 XFreeGC(xdisplay_, window_graphics_context_);
134 window_graphics_context_ = NULL;
137 XSync(xdisplay_, False);
140 bool NativeViewGLSurfaceOSMesa::Resize(const gfx::Size& new_size) {
141 if (!GLSurfaceOSMesa::Resize(new_size))
142 return false;
144 XWindowAttributes attributes;
145 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) {
146 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << ".";
147 return false;
150 // Destroy the previous pixmap and graphics context.
151 if (pixmap_graphics_context_) {
152 XFreeGC(xdisplay_, pixmap_graphics_context_);
153 pixmap_graphics_context_ = NULL;
155 if (pixmap_) {
156 XFreePixmap(xdisplay_, pixmap_);
157 pixmap_ = 0;
160 // Recreate a pixmap to hold the frame.
161 pixmap_ = XCreatePixmap(xdisplay_,
162 window_,
163 new_size.width(),
164 new_size.height(),
165 attributes.depth);
166 if (!pixmap_) {
167 LOG(ERROR) << "XCreatePixmap failed.";
168 return false;
171 // Recreate a graphics context for the pixmap.
172 pixmap_graphics_context_ = XCreateGC(xdisplay_, pixmap_, 0, NULL);
173 if (!pixmap_graphics_context_) {
174 LOG(ERROR) << "XCreateGC failed";
175 return false;
178 return true;
181 bool NativeViewGLSurfaceOSMesa::IsOffscreen() {
182 return false;
185 bool NativeViewGLSurfaceOSMesa::SwapBuffers() {
186 TRACE_EVENT2("gpu", "NativeViewGLSurfaceOSMesa:RealSwapBuffers",
187 "width", GetSize().width(),
188 "height", GetSize().height());
190 gfx::Size size = GetSize();
192 XWindowAttributes attributes;
193 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) {
194 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << ".";
195 return false;
198 // Copy the frame into the pixmap.
199 gfx::PutARGBImage(xdisplay_,
200 attributes.visual,
201 attributes.depth,
202 pixmap_,
203 pixmap_graphics_context_,
204 static_cast<const uint8*>(GetHandle()),
205 size.width(),
206 size.height());
208 // Copy the pixmap to the window.
209 XCopyArea(xdisplay_,
210 pixmap_,
211 window_,
212 window_graphics_context_,
215 size.width(),
216 size.height(),
220 return true;
223 bool NativeViewGLSurfaceOSMesa::SupportsPostSubBuffer() {
224 return true;
227 bool NativeViewGLSurfaceOSMesa::PostSubBuffer(
228 int x, int y, int width, int height) {
229 gfx::Size size = GetSize();
231 // Move (0,0) from lower-left to upper-left
232 y = size.height() - y - height;
234 XWindowAttributes attributes;
235 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) {
236 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << ".";
237 return false;
240 // Copy the frame into the pixmap.
241 gfx::PutARGBImage(xdisplay_,
242 attributes.visual,
243 attributes.depth,
244 pixmap_,
245 pixmap_graphics_context_,
246 static_cast<const uint8*>(GetHandle()),
247 size.width(),
248 size.height(),
253 width,
254 height);
256 // Copy the pixmap to the window.
257 XCopyArea(xdisplay_,
258 pixmap_,
259 window_,
260 window_graphics_context_,
263 width,
264 height,
268 return true;
271 NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() {
272 Destroy();
275 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
276 gfx::AcceleratedWidget window) {
277 TRACE_EVENT0("gpu", "GLSurface::CreateViewGLSurface");
278 switch (GetGLImplementation()) {
279 case kGLImplementationOSMesaGL: {
280 scoped_refptr<GLSurface> surface(
281 new NativeViewGLSurfaceOSMesa(window));
282 if (!surface->Initialize())
283 return NULL;
285 return surface;
287 case kGLImplementationDesktopGL: {
288 scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceGLX(window));
289 if (!surface->Initialize())
290 return NULL;
292 return surface;
294 case kGLImplementationEGLGLES2: {
295 DCHECK(window != gfx::kNullAcceleratedWidget);
296 scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceEGL(window));
297 if (!surface->Initialize())
298 return NULL;
300 return surface;
302 case kGLImplementationMockGL:
303 return new GLSurfaceStub;
304 default:
305 NOTREACHED();
306 return NULL;
310 scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
311 const gfx::Size& size) {
312 TRACE_EVENT0("gpu", "GLSurface::CreateOffscreenGLSurface");
313 switch (GetGLImplementation()) {
314 case kGLImplementationOSMesaGL: {
315 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa(OSMESA_RGBA,
316 size));
317 if (!surface->Initialize())
318 return NULL;
320 return surface;
322 case kGLImplementationDesktopGL: {
323 scoped_refptr<GLSurface> surface(new PbufferGLSurfaceGLX(size));
324 if (!surface->Initialize())
325 return NULL;
327 return surface;
329 case kGLImplementationEGLGLES2: {
330 scoped_refptr<GLSurface> surface(new PbufferGLSurfaceEGL(size));
331 if (!surface->Initialize())
332 return NULL;
334 return surface;
336 case kGLImplementationMockGL:
337 return new GLSurfaceStub;
338 default:
339 NOTREACHED();
340 return NULL;
344 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
345 return gfx::GetXDisplay();
348 } // namespace gfx