OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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 #include "ui/gl/gl_surface_osmesa_x11.h" |
| 6 |
| 7 #include <stdint.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/trace_event/trace_event.h" |
| 12 #include "ui/gfx/x/x11_types.h" |
| 13 #include "ui/gl/gl_bindings.h" |
| 14 #include "ui/gl/gl_implementation.h" |
| 15 |
| 16 namespace gl { |
| 17 |
| 18 GLSurfaceOSMesaX11::GLSurfaceOSMesaX11(gfx::AcceleratedWidget window) |
| 19 : GLSurfaceOSMesa(SURFACE_OSMESA_BGRA, gfx::Size(1, 1)), |
| 20 xdisplay_(gfx::GetXDisplay()), |
| 21 window_graphics_context_(0), |
| 22 window_(window), |
| 23 pixmap_graphics_context_(0), |
| 24 pixmap_(0) { |
| 25 DCHECK(xdisplay_); |
| 26 DCHECK(window_); |
| 27 } |
| 28 |
| 29 // static |
| 30 bool GLSurfaceOSMesaX11::InitializeOneOff() { |
| 31 static bool initialized = false; |
| 32 if (initialized) |
| 33 return true; |
| 34 |
| 35 if (!gfx::GetXDisplay()) { |
| 36 LOG(ERROR) << "XOpenDisplay failed."; |
| 37 return false; |
| 38 } |
| 39 |
| 40 initialized = true; |
| 41 return true; |
| 42 } |
| 43 |
| 44 bool GLSurfaceOSMesaX11::Initialize(GLSurface::Format format) { |
| 45 if (!GLSurfaceOSMesa::Initialize(format)) |
| 46 return false; |
| 47 |
| 48 window_graphics_context_ = XCreateGC(xdisplay_, window_, 0, NULL); |
| 49 if (!window_graphics_context_) { |
| 50 LOG(ERROR) << "XCreateGC failed."; |
| 51 Destroy(); |
| 52 return false; |
| 53 } |
| 54 |
| 55 return true; |
| 56 } |
| 57 |
| 58 void GLSurfaceOSMesaX11::Destroy() { |
| 59 if (pixmap_graphics_context_) { |
| 60 XFreeGC(xdisplay_, pixmap_graphics_context_); |
| 61 pixmap_graphics_context_ = NULL; |
| 62 } |
| 63 |
| 64 if (pixmap_) { |
| 65 XFreePixmap(xdisplay_, pixmap_); |
| 66 pixmap_ = 0; |
| 67 } |
| 68 |
| 69 if (window_graphics_context_) { |
| 70 XFreeGC(xdisplay_, window_graphics_context_); |
| 71 window_graphics_context_ = NULL; |
| 72 } |
| 73 |
| 74 XSync(xdisplay_, False); |
| 75 } |
| 76 |
| 77 bool GLSurfaceOSMesaX11::Resize(const gfx::Size& new_size, |
| 78 float scale_factor, |
| 79 bool alpha) { |
| 80 if (!GLSurfaceOSMesa::Resize(new_size, scale_factor, alpha)) |
| 81 return false; |
| 82 |
| 83 XWindowAttributes attributes; |
| 84 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { |
| 85 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; |
| 86 return false; |
| 87 } |
| 88 |
| 89 // Destroy the previous pixmap and graphics context. |
| 90 if (pixmap_graphics_context_) { |
| 91 XFreeGC(xdisplay_, pixmap_graphics_context_); |
| 92 pixmap_graphics_context_ = NULL; |
| 93 } |
| 94 if (pixmap_) { |
| 95 XFreePixmap(xdisplay_, pixmap_); |
| 96 pixmap_ = 0; |
| 97 } |
| 98 |
| 99 // Recreate a pixmap to hold the frame. |
| 100 pixmap_ = XCreatePixmap(xdisplay_, window_, new_size.width(), |
| 101 new_size.height(), attributes.depth); |
| 102 if (!pixmap_) { |
| 103 LOG(ERROR) << "XCreatePixmap failed."; |
| 104 return false; |
| 105 } |
| 106 |
| 107 // Recreate a graphics context for the pixmap. |
| 108 pixmap_graphics_context_ = XCreateGC(xdisplay_, pixmap_, 0, NULL); |
| 109 if (!pixmap_graphics_context_) { |
| 110 LOG(ERROR) << "XCreateGC failed"; |
| 111 return false; |
| 112 } |
| 113 |
| 114 return true; |
| 115 } |
| 116 |
| 117 bool GLSurfaceOSMesaX11::IsOffscreen() { |
| 118 return false; |
| 119 } |
| 120 |
| 121 gfx::SwapResult GLSurfaceOSMesaX11::SwapBuffers() { |
| 122 TRACE_EVENT2("gpu", "GLSurfaceOSMesaX11:RealSwapBuffers", "width", |
| 123 GetSize().width(), "height", GetSize().height()); |
| 124 |
| 125 gfx::Size size = GetSize(); |
| 126 |
| 127 XWindowAttributes attributes; |
| 128 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { |
| 129 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; |
| 130 return gfx::SwapResult::SWAP_FAILED; |
| 131 } |
| 132 |
| 133 // Copy the frame into the pixmap. |
| 134 gfx::PutARGBImage(xdisplay_, attributes.visual, attributes.depth, pixmap_, |
| 135 pixmap_graphics_context_, |
| 136 static_cast<const uint8_t*>(GetHandle()), size.width(), |
| 137 size.height()); |
| 138 |
| 139 // Copy the pixmap to the window. |
| 140 XCopyArea(xdisplay_, pixmap_, window_, window_graphics_context_, 0, 0, |
| 141 size.width(), size.height(), 0, 0); |
| 142 |
| 143 return gfx::SwapResult::SWAP_ACK; |
| 144 } |
| 145 |
| 146 bool GLSurfaceOSMesaX11::SupportsPostSubBuffer() { |
| 147 return true; |
| 148 } |
| 149 |
| 150 gfx::SwapResult GLSurfaceOSMesaX11::PostSubBuffer(int x, |
| 151 int y, |
| 152 int width, |
| 153 int height) { |
| 154 gfx::Size size = GetSize(); |
| 155 |
| 156 // Move (0,0) from lower-left to upper-left |
| 157 y = size.height() - y - height; |
| 158 |
| 159 XWindowAttributes attributes; |
| 160 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { |
| 161 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; |
| 162 return gfx::SwapResult::SWAP_FAILED; |
| 163 } |
| 164 |
| 165 // Copy the frame into the pixmap. |
| 166 gfx::PutARGBImage(xdisplay_, attributes.visual, attributes.depth, pixmap_, |
| 167 pixmap_graphics_context_, |
| 168 static_cast<const uint8_t*>(GetHandle()), size.width(), |
| 169 size.height(), x, y, x, y, width, height); |
| 170 |
| 171 // Copy the pixmap to the window. |
| 172 XCopyArea(xdisplay_, pixmap_, window_, window_graphics_context_, x, y, width, |
| 173 height, x, y); |
| 174 |
| 175 return gfx::SwapResult::SWAP_ACK; |
| 176 } |
| 177 |
| 178 GLSurfaceOSMesaX11::~GLSurfaceOSMesaX11() { |
| 179 Destroy(); |
| 180 } |
| 181 |
| 182 } // namespace gl |
OLD | NEW |