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

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

Issue 8414001: Unnecessary file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/accelerated_surface_container_linux.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/rect.h"
19 #include "ui/gfx/transform.h"
20
21 namespace {
22
23 class AcceleratedSurfaceContainerLinuxEGL
24 : public AcceleratedSurfaceContainerLinux {
25 public:
26 explicit AcceleratedSurfaceContainerLinuxEGL(const gfx::Size& size);
27
28 virtual bool Initialize(uint64* surface_id) OVERRIDE;
29
30 // TextureGL implementation
31 virtual void Draw(const ui::TextureDrawParams& params,
32 const gfx::Rect& clip_bounds_in_texture) OVERRIDE;
33
34 private:
35 virtual ~AcceleratedSurfaceContainerLinuxEGL();
36
37 void* image_;
38
39 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerLinuxEGL);
40 };
41
42 class AcceleratedSurfaceContainerLinuxGLX
43 : public AcceleratedSurfaceContainerLinux {
44 public:
45 explicit AcceleratedSurfaceContainerLinuxGLX(const gfx::Size& size);
46
47 virtual bool Initialize(uint64* surface_id) OVERRIDE;
48
49 // TextureGL implementation
50 virtual void Draw(const ui::TextureDrawParams& params,
51 const gfx::Rect& clip_bounds_in_texture) OVERRIDE;
52
53 protected:
54 static bool InitializeOneOff();
55
56 static base::LazyInstance<GLXFBConfig> fbconfig_;
57
58 private:
59 virtual ~AcceleratedSurfaceContainerLinuxGLX();
60
61 XID pixmap_;
62 XID glx_pixmap_;
63
64 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerLinuxGLX);
65 };
66
67 class AcceleratedSurfaceContainerLinuxOSMesa
68 : public AcceleratedSurfaceContainerLinux {
69 public:
70 explicit AcceleratedSurfaceContainerLinuxOSMesa(const gfx::Size& size);
71
72 virtual bool Initialize(uint64* surface_id) OVERRIDE;
73
74 // TextureGL implementation
75 virtual void Draw(const ui::TextureDrawParams& params,
76 const gfx::Rect& clip_bounds_in_texture) OVERRIDE;
77
78 // Some implementations of this class use shared memory, this gives the handle
79 // to the shared buffer, which is part of the surface container.
80 // When shared memory is not used, this will return
81 // TransportDIB::DefaultHandleValue().
82 virtual TransportDIB::Handle Handle() const OVERRIDE;
83
84 private:
85 virtual ~AcceleratedSurfaceContainerLinuxOSMesa();
86
87 scoped_ptr<TransportDIB> shared_mem_;
88
89 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerLinuxOSMesa);
90 };
91
92 class ScopedPtrXFree {
93 public:
94 void operator()(void* x) const {
95 ::XFree(x);
96 }
97 };
98
99 // static
100 base::LazyInstance<GLXFBConfig> AcceleratedSurfaceContainerLinuxGLX::fbconfig_(
101 base::LINKER_INITIALIZED);
102
103 AcceleratedSurfaceContainerLinuxEGL::AcceleratedSurfaceContainerLinuxEGL(
104 const gfx::Size& size)
105 : AcceleratedSurfaceContainerLinux(size),
106 image_(NULL) {
107 }
108
109 bool AcceleratedSurfaceContainerLinuxEGL::Initialize(uint64* surface_id) {
110 ui::SharedResources* instance = ui::SharedResources::GetInstance();
111 DCHECK(instance);
112 instance->MakeSharedContextCurrent();
113
114 image_ = eglCreateImageKHR(
115 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT,
116 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(*surface_id), NULL);
117
118 glGenTextures(1, &texture_id_);
119 glBindTexture(GL_TEXTURE_2D, texture_id_);
120 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
121 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
124 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_);
125 glFlush();
126
127 return true;
128 }
129
130 AcceleratedSurfaceContainerLinuxEGL::~AcceleratedSurfaceContainerLinuxEGL() {
131 ui::SharedResources* instance = ui::SharedResources::GetInstance();
132 DCHECK(instance);
133 instance->MakeSharedContextCurrent();
134
135 eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_);
136 glFlush();
137 }
138
139 void AcceleratedSurfaceContainerLinuxEGL::Draw(
140 const ui::TextureDrawParams& params,
141 const gfx::Rect& clip_bounds_in_texture) {
142 ui::SharedResources* instance = ui::SharedResources::GetInstance();
143 DCHECK(instance);
144
145 ui::TextureDrawParams modified_params = params;
146 modified_params.vertically_flipped = true;
147
148 DrawInternal(*instance->program_no_swizzle(),
149 modified_params,
150 clip_bounds_in_texture);
151 }
152
153 AcceleratedSurfaceContainerLinuxGLX::AcceleratedSurfaceContainerLinuxGLX(
154 const gfx::Size& size)
155 : AcceleratedSurfaceContainerLinux(size),
156 pixmap_(0),
157 glx_pixmap_(0) {
158 }
159
160 bool AcceleratedSurfaceContainerLinuxGLX::Initialize(uint64* surface_id) {
161 ui::SharedResources* instance = ui::SharedResources::GetInstance();
162 DCHECK(instance);
163 instance->MakeSharedContextCurrent();
164
165 if (!AcceleratedSurfaceContainerLinuxGLX::InitializeOneOff())
166 return false;
167
168 // Create pixmap from window.
169 // We receive a window here rather than a pixmap directly because drivers
170 // require (or required) that the pixmap used to create the GL texture be
171 // created in the same process as the texture.
172 Display* dpy = instance->GetDisplay();
173 pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_id);
174
175 // Wrap the pixmap in a GLXPixmap
176 const int pixmapAttribs[] = {
177 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
178 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
179 0
180 };
181
182 glx_pixmap_ = glXCreatePixmap(
183 dpy, fbconfig_.Get(), pixmap_, pixmapAttribs);
184
185 // Create texture.
186 glGenTextures(1, &texture_id_);
187 glBindTexture(GL_TEXTURE_2D, texture_id_);
188 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
189 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
192
193 return true;
194 }
195
196 AcceleratedSurfaceContainerLinuxGLX::~AcceleratedSurfaceContainerLinuxGLX() {
197 ui::SharedResources* instance = ui::SharedResources::GetInstance();
198 DCHECK(instance);
199 instance->MakeSharedContextCurrent();
200
201 Display* dpy = instance->GetDisplay();
202 if (glx_pixmap_)
203 glXDestroyGLXPixmap(dpy, glx_pixmap_);
204 if (pixmap_)
205 XFreePixmap(dpy, pixmap_);
206 }
207
208 void AcceleratedSurfaceContainerLinuxGLX::Draw(
209 const ui::TextureDrawParams& params,
210 const gfx::Rect& clip_bounds_in_texture) {
211 ui::SharedResources* instance = ui::SharedResources::GetInstance();
212 DCHECK(instance);
213
214 Display* dpy = instance->GetDisplay();
215
216 glBindTexture(GL_TEXTURE_2D, texture_id_);
217 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
218 DrawInternal(*instance->program_no_swizzle(),
219 params,
220 clip_bounds_in_texture);
221 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT);
222 }
223
224 // static
225 bool AcceleratedSurfaceContainerLinuxGLX::InitializeOneOff()
226 {
227 static bool initialized = false;
228 if (initialized)
229 return true;
230
231 ui::SharedResources* instance = ui::SharedResources::GetInstance();
232 DCHECK(instance);
233
234 Display* dpy = instance->GetDisplay();
235 int event_base, error_base;
236 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) {
237 int major = 0, minor = 2;
238 XCompositeQueryVersion(dpy, &major, &minor);
239 if (major == 0 && minor < 2) {
240 LOG(ERROR) << "Pixmap from window not supported.";
241 return false;
242 }
243 }
244
245 // Wrap the pixmap in a GLXPixmap
246 int screen = DefaultScreen(dpy);
247 XWindowAttributes gwa;
248 XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa);
249 unsigned int visualid = XVisualIDFromVisual(gwa.visual);
250
251 int nfbconfigs, config;
252 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs(
253 glXGetFBConfigs(dpy, screen, &nfbconfigs));
254
255 for (config = 0; config < nfbconfigs; config++) {
256 XVisualInfo* visinfo = glXGetVisualFromFBConfig(
257 dpy, fbconfigs.get()[config]);
258 if (!visinfo || visinfo->visualid != visualid)
259 continue;
260
261 int value;
262 glXGetFBConfigAttrib(dpy,
263 fbconfigs.get()[config],
264 GLX_DRAWABLE_TYPE,
265 &value);
266 if (!(value & GLX_PIXMAP_BIT))
267 continue;
268
269 glXGetFBConfigAttrib(dpy,
270 fbconfigs.get()[config],
271 GLX_BIND_TO_TEXTURE_TARGETS_EXT,
272 &value);
273 if (!(value & GLX_TEXTURE_2D_BIT_EXT))
274 continue;
275
276 glXGetFBConfigAttrib(dpy,
277 fbconfigs.get()[config],
278 GLX_BIND_TO_TEXTURE_RGB_EXT,
279 &value);
280 if (value == GL_FALSE)
281 continue;
282
283 break;
284 }
285
286 if (config == nfbconfigs) {
287 LOG(ERROR)
288 << "Could not find configuration suitable for binding a pixmap "
289 << "as a texture.";
290 return false;
291 }
292
293 fbconfig_.Get() = fbconfigs.get()[config];
294
295 initialized = true;
296 return initialized;
297 }
298
299 AcceleratedSurfaceContainerLinuxOSMesa::AcceleratedSurfaceContainerLinuxOSMesa(
300 const gfx::Size& size)
301 : AcceleratedSurfaceContainerLinux(size) {
302 }
303
304 bool AcceleratedSurfaceContainerLinuxOSMesa::Initialize(uint64* surface_id) {
305 static uint32 next_id = 1;
306
307 ui::SharedResources* instance = ui::SharedResources::GetInstance();
308 DCHECK(instance);
309 instance->MakeSharedContextCurrent();
310
311 // We expect to make the id here, so don't want the other end giving us one
312 DCHECK_EQ(*surface_id, static_cast<uint64>(0));
313
314 // It's possible that this ID gneration could clash with IDs from other
315 // AcceleratedSurfaceContainerLinux* objects, however we should never have
316 // ids active from more than one type at the same time, so we have free
317 // reign of the id namespace.
318 *surface_id = next_id++;
319
320 shared_mem_.reset(
321 TransportDIB::Create(size_.GetArea() * 4, // GL_RGBA=4 B/px
322 *surface_id));
323 // Create texture.
324 glGenTextures(1, &texture_id_);
325 glBindTexture(GL_TEXTURE_2D, texture_id_);
326 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
327 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
328 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
329 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
330
331 // we generate the ID to be used here.
332 return true;
333 }
334
335 void AcceleratedSurfaceContainerLinuxOSMesa::Draw(
336 const ui::TextureDrawParams& params,
337 const gfx::Rect& clip_bounds_in_texture) {
338 ui::SharedResources* instance = ui::SharedResources::GetInstance();
339 DCHECK(instance);
340
341 if (shared_mem_.get()) {
342 glBindTexture(GL_TEXTURE_2D, texture_id_);
343 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
344 size_.width(), size_.height(), 0,
345 GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory());
346
347 DrawInternal(*instance->program_no_swizzle(),
348 params,
349 clip_bounds_in_texture);
350 }
351 }
352
353 TransportDIB::Handle AcceleratedSurfaceContainerLinuxOSMesa::Handle() const {
354 if (shared_mem_.get())
355 return shared_mem_->handle();
356 else
357 return TransportDIB::DefaultHandleValue();
358 }
359
360 AcceleratedSurfaceContainerLinuxOSMesa::
361 ~AcceleratedSurfaceContainerLinuxOSMesa() {
362 }
363
364 } // namespace
365
366 AcceleratedSurfaceContainerLinux::AcceleratedSurfaceContainerLinux(
367 const gfx::Size& size) : TextureGL(size) {
368 }
369
370 TransportDIB::Handle AcceleratedSurfaceContainerLinux::Handle() const {
371 return TransportDIB::DefaultHandleValue();
372 }
373
374 // static
375 AcceleratedSurfaceContainerLinux*
376 AcceleratedSurfaceContainerLinux::CreateAcceleratedSurfaceContainer(
377 const gfx::Size& size) {
378 switch (gfx::GetGLImplementation()) {
379 case gfx::kGLImplementationDesktopGL:
380 return new AcceleratedSurfaceContainerLinuxGLX(size);
381 case gfx::kGLImplementationEGLGLES2:
382 return new AcceleratedSurfaceContainerLinuxEGL(size);
383 case gfx::kGLImplementationOSMesaGL:
384 return new AcceleratedSurfaceContainerLinuxOSMesa(size);
385 default:
386 NOTREACHED();
387 return NULL;
388 }
389 }
390
391 void AcceleratedSurfaceContainerLinux::SetCanvas(
392 const SkCanvas& canvas,
393 const gfx::Point& origin,
394 const gfx::Size& overall_size) {
395 NOTREACHED();
396 }
397
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698