Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Side by Side Diff: content/browser/renderer_host/image_transport_client.cc

Issue 8307001: Enable accelerated compositing of web pages when using webkit compositor (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: rebase Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "content/browser/renderer_host/image_transport_client.h"
6
7 #include <X11/Xlib.h>
8 #include <X11/extensions/Xcomposite.h>
9
10 #include "base/lazy_instance.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "third_party/angle/include/EGL/egl.h"
13 #include "third_party/angle/include/EGL/eglext.h"
14 #include "ui/gfx/gl/gl_bindings.h"
15 #include "ui/gfx/gl/gl_implementation.h"
16 #include "ui/gfx/gl/gl_surface_egl.h"
17 #include "ui/gfx/gl/gl_surface_glx.h"
18 #include "ui/gfx/size.h"
19
20 namespace {
21
22 class ScopedPtrXFree {
23 public:
24 void operator()(void* x) const {
25 ::XFree(x);
26 }
27 };
28
29 GLuint CreateTexture() {
30 GLuint texture;
31 glGenTextures(1, &texture);
32 glBindTexture(GL_TEXTURE_2D, texture);
33 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
34 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
35 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
36 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
37 return texture;
38 }
39
40 class ImageTransportClientEGL : public ImageTransportClient {
41 public:
42 explicit ImageTransportClientEGL(ui::SharedResources* resources)
43 : resources_(resources),
44 image_(NULL) {
45 }
46
47 virtual ~ImageTransportClientEGL() {
48 if (image_) {
49 resources_->MakeSharedContextCurrent();
50 eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_);
51 glFlush();
52 }
53 }
54
55 virtual unsigned int Initialize(uint64* surface_id) {
56 resources_->MakeSharedContextCurrent();
57 image_ = eglCreateImageKHR(
58 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT,
59 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(*surface_id), NULL);
60 if (!image_)
61 return 0;
62 GLuint texture = CreateTexture();
63 glBindTexture(GL_TEXTURE_2D, texture);
64 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_);
65 glFlush();
66 return texture;
67 }
68
69 virtual void Acquire() { }
70 virtual void Release() { }
71 virtual bool Flipped() { return true; }
72 virtual TransportDIB::Handle Handle() const {
73 return TransportDIB::DefaultHandleValue();
74 }
75
76 private:
77 ui::SharedResources* resources_;
78 EGLImageKHR image_;
79 };
80
81 class ImageTransportClientGLX : public ImageTransportClient {
82 public:
83 explicit ImageTransportClientGLX(ui::SharedResources* resources)
84 : resources_(resources),
85 pixmap_(0),
86 glx_pixmap_(0),
87 texture_(0) {
88 }
89
90 virtual ~ImageTransportClientGLX() {
91 Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
92 if (glx_pixmap_)
93 glXDestroyGLXPixmap(dpy, glx_pixmap_);
94 if (pixmap_)
95 XFreePixmap(dpy, pixmap_);
96 }
97
98 virtual unsigned int Initialize(uint64* surface_id) {
99 resources_->MakeSharedContextCurrent();
100 if (!InitializeOneOff())
101 return 0;
102
103 // Create pixmap from window.
104 // We receive a window here rather than a pixmap directly because drivers
105 // require (or required) that the pixmap used to create the GL texture be
106 // created in the same process as the texture.
107 Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
108 pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_id);
109
110 const int pixmapAttribs[] = {
111 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
112 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
113 0
114 };
115
116 glx_pixmap_ = glXCreatePixmap(dpy, fbconfig_.Get(), pixmap_, pixmapAttribs);
117
118 texture_ = CreateTexture();
119 return texture_;
120 }
121
122 virtual void Acquire() {
123 Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
124 glBindTexture(GL_TEXTURE_2D, texture_);
125 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
126 }
127
128 virtual void Release() {
129 Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
130 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT);
131 }
132
133 virtual bool Flipped() { return false; }
134 virtual TransportDIB::Handle Handle() const {
135 return TransportDIB::DefaultHandleValue();
136 }
137
138 private:
139 static bool InitializeOneOff() {
140 static bool initialized = false;
141 if (initialized)
142 return true;
143
144 Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
145
146 int event_base, error_base;
147 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) {
148 int major = 0, minor = 2;
149 XCompositeQueryVersion(dpy, &major, &minor);
150 if (major == 0 && minor < 2) {
151 LOG(ERROR) << "Pixmap from window not supported.";
152 return false;
153 }
154 }
155 // Wrap the pixmap in a GLXPixmap
156 int screen = DefaultScreen(dpy);
157 XWindowAttributes gwa;
158 XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa);
159 unsigned int visualid = XVisualIDFromVisual(gwa.visual);
160
161 int nfbconfigs, config;
162 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs(
163 glXGetFBConfigs(dpy, screen, &nfbconfigs));
164
165 for (config = 0; config < nfbconfigs; config++) {
166 XVisualInfo* visinfo = glXGetVisualFromFBConfig(
167 dpy, fbconfigs.get()[config]);
168 if (!visinfo || visinfo->visualid != visualid)
169 continue;
170
171 int value;
172 glXGetFBConfigAttrib(dpy,
173 fbconfigs.get()[config],
174 GLX_DRAWABLE_TYPE,
175 &value);
176 if (!(value & GLX_PIXMAP_BIT))
177 continue;
178
179 glXGetFBConfigAttrib(dpy,
180 fbconfigs.get()[config],
181 GLX_BIND_TO_TEXTURE_TARGETS_EXT,
182 &value);
183 if (!(value & GLX_TEXTURE_2D_BIT_EXT))
184 continue;
185
186 glXGetFBConfigAttrib(dpy,
187 fbconfigs.get()[config],
188 GLX_BIND_TO_TEXTURE_RGB_EXT,
189 &value);
190 if (value == GL_FALSE)
191 continue;
192
193 break;
194 }
195
196 if (config == nfbconfigs) {
197 LOG(ERROR)
198 << "Could not find configuration suitable for binding a pixmap "
199 << "as a texture.";
200 return false;
201 }
202 fbconfig_.Get() = fbconfigs.get()[config];
203 initialized = true;
204 return initialized;
205 }
206
207 ui::SharedResources* resources_;
208 XID pixmap_;
209 XID glx_pixmap_;
210 GLuint texture_;
211 static base::LazyInstance<GLXFBConfig> fbconfig_;
212 };
213
214 base::LazyInstance<GLXFBConfig> ImageTransportClientGLX::fbconfig_(
215 base::LINKER_INITIALIZED);
216
217 class ImageTransportClientOSMesa : public ImageTransportClient {
218 public:
219 ImageTransportClientOSMesa(ui::SharedResources* resources,
220 const gfx::Size& size)
221 : resources_(resources),
222 size_(size),
223 texture_(0) {
224 }
225
226 virtual ~ImageTransportClientOSMesa() {
227 }
228
229 virtual unsigned int Initialize(uint64* surface_id) {
230 // We expect to make the id here, so don't want the other end giving us one
231 DCHECK_EQ(*surface_id, static_cast<uint64>(0));
232
233 // It's possible that this ID gneration could clash with IDs from other
234 // AcceleratedSurfaceContainerTouch* objects, however we should never have
235 // ids active from more than one type at the same time, so we have free
236 // reign of the id namespace.
237 *surface_id = next_id_++;
238
239 shared_mem_.reset(
240 TransportDIB::Create(size_.GetArea() * 4, // GL_RGBA=4 B/px
241 *surface_id));
242 if (!shared_mem_.get())
243 return 0;
244
245 resources_->MakeSharedContextCurrent();
246 texture_ = CreateTexture();
247 return texture_;
248 }
249
250 virtual void Acquire() {
251 glBindTexture(GL_TEXTURE_2D, texture_);
252 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
253 size_.width(), size_.height(), 0,
254 GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory());
255 }
256
257 virtual void Release() { }
258 virtual bool Flipped() { return false; }
259 virtual TransportDIB::Handle Handle() const { return shared_mem_->handle(); }
260
261 private:
262 ui::SharedResources* resources_;
263 gfx::Size size_;
264 scoped_ptr<TransportDIB> shared_mem_;
265 GLuint texture_;
266 static uint32 next_id_;
267 };
268 uint32 ImageTransportClientOSMesa::next_id_ = 0;
269
270 } // anonymous namespace
271
272 ImageTransportClient* ImageTransportClient::Create(
273 ui::SharedResources* resources,
274 const gfx::Size& size) {
275 switch (gfx::GetGLImplementation()) {
276 case gfx::kGLImplementationDesktopGL:
277 return new ImageTransportClientGLX(resources);
278 case gfx::kGLImplementationEGLGLES2:
279 return new ImageTransportClientEGL(resources);
280 case gfx::kGLImplementationOSMesaGL:
281 return new ImageTransportClientOSMesa(resources, size);
282 default:
283 NOTREACHED();
284 return NULL;
285 }
286 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/image_transport_client.h ('k') | content/browser/renderer_host/render_widget_host_view_aura.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698