OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 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/common/gpu/media/vaapi_picture_provider_x11.h" | |
6 #include "ui/gl/gl_bindings.h" | |
7 #include "ui/gl/gl_context_glx.h" | |
8 #include "ui/gl/gl_image.h" | |
9 #include "ui/gl/scoped_binders.h" | |
10 | |
11 namespace content { | |
12 | |
13 class TFPPicture : public VaapiPictureProvider::Picture { | |
Pawel Osciak
2014/10/26 13:06:46
Please do not define nontrivial methods in the bod
llandwerlin-old
2014/10/29 13:52:48
Acknowledged.
| |
14 public: | |
15 TFPPicture(scoped_refptr<VaapiWrapper> vaapi_wrapper, | |
16 gfx::GLContextGLX* glx_context, | |
17 const base::Callback<bool(void)> make_context_current, | |
18 int32 picture_buffer_id, | |
19 uint32 texture_id, | |
20 const gfx::Size& size) | |
21 : Picture(picture_buffer_id, texture_id, size), | |
22 vaapi_wrapper_(vaapi_wrapper), | |
23 glx_context_(glx_context), | |
24 make_context_current_(make_context_current), | |
25 x_display_(glx_context_->display()) {} | |
26 | |
27 virtual ~TFPPicture() { | |
28 if (glx_pixmap_ && make_context_current_.Run()) { | |
29 glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); | |
30 glXDestroyPixmap(x_display_, glx_pixmap_); | |
31 } | |
32 | |
33 if (x_pixmap_) | |
34 XFreePixmap(x_display_, x_pixmap_); | |
35 XSync(x_display_, False); // Needed to work around buggy vdpau-driver. | |
36 } | |
37 | |
38 bool Initialize(GLXFBConfig& fb_config) { | |
39 if (!make_context_current_.Run()) | |
40 return false; | |
41 | |
42 XWindowAttributes win_attr; | |
43 int screen = DefaultScreen(x_display_); | |
44 XGetWindowAttributes(x_display_, RootWindow(x_display_, screen), &win_attr); | |
45 // TODO(posciak): pass the depth required by libva, not the RootWindow's | |
46 // depth | |
47 x_pixmap_ = XCreatePixmap(x_display_, | |
48 RootWindow(x_display_, screen), | |
49 size().width(), | |
50 size().height(), | |
51 win_attr.depth); | |
52 if (!x_pixmap_) { | |
53 DVLOG(1) << "Failed creating an X Pixmap for TFP"; | |
54 return false; | |
55 } | |
56 | |
57 static const int pixmap_attr[] = { | |
58 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, | |
59 GLX_TEXTURE_FORMAT_RGB_EXT, GL_NONE, | |
60 }; | |
61 | |
62 glx_pixmap_ = | |
63 glXCreatePixmap(x_display_, fb_config, x_pixmap_, pixmap_attr); | |
64 if (!glx_pixmap_) { | |
65 // x_pixmap_ will be freed in the destructor. | |
66 DVLOG(1) << "Failed creating a GLX Pixmap for TFP"; | |
67 return false; | |
68 } | |
69 | |
70 return true; | |
71 } | |
72 | |
73 bool DownloadFromSurface(VASurfaceID va_surface_id, | |
74 const gfx::Size& surface_size) OVERRIDE { | |
75 if (!make_context_current_.Run()) { | |
76 DVLOG(1) << "Failed making gl context current"; | |
77 return false; | |
78 } | |
79 | |
80 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id()); | |
81 glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); | |
82 if (glGetError() != GL_NO_ERROR) | |
83 return false; | |
84 | |
85 return vaapi_wrapper_->PutSurfaceIntoPixmap( | |
86 va_surface_id, x_pixmap_, size()); | |
87 } | |
88 | |
89 private: | |
90 scoped_refptr<VaapiWrapper> vaapi_wrapper_; | |
91 | |
92 gfx::GLContextGLX* glx_context_; | |
93 base::Callback<bool(void)> make_context_current_; | |
94 Display* x_display_; | |
95 | |
96 Pixmap x_pixmap_; | |
97 GLXPixmap glx_pixmap_; | |
98 | |
99 DISALLOW_COPY_AND_ASSIGN(TFPPicture); | |
100 }; | |
101 | |
102 class XFreeDeleter { | |
103 public: | |
104 void operator()(void* x) const { ::XFree(x); } | |
105 }; | |
106 | |
107 X11VaapiPictureProvider::X11VaapiPictureProvider( | |
108 scoped_refptr<VaapiWrapper> vaapi_wrapper, | |
109 gfx::GLContextGLX* glx_context, | |
110 const base::Callback<bool(void)> make_context_current) | |
111 : glx_context_(glx_context), | |
112 make_context_current_(make_context_current), | |
113 x_display_(glx_context_->display()), | |
114 vaapi_wrapper_(vaapi_wrapper) { | |
115 } | |
116 | |
117 X11VaapiPictureProvider::~X11VaapiPictureProvider() { | |
118 } | |
119 | |
120 linked_ptr<VaapiPictureProvider::Picture> | |
121 X11VaapiPictureProvider::CreatePicture(int32 picture_buffer_id, | |
122 uint32 texture_id, | |
123 const gfx::Size& size) { | |
124 TFPPicture* tfp_picture = new TFPPicture(vaapi_wrapper_, | |
125 glx_context_, | |
126 make_context_current_, | |
127 picture_buffer_id, | |
128 texture_id, | |
129 size); | |
130 linked_ptr<VaapiPictureProvider::Picture> picture(tfp_picture); | |
131 | |
132 if (!tfp_picture->Initialize(fb_config_)) | |
133 picture.reset(); | |
134 | |
135 return picture; | |
136 } | |
137 | |
138 bool X11VaapiPictureProvider::Initialize() { | |
139 if (!make_context_current_.Run()) { | |
140 DVLOG(1) << "Couldn't make context current"; | |
141 return false; | |
142 } | |
143 | |
144 const int fbconfig_attr[] = { | |
145 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, | |
146 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, | |
147 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, | |
148 GLX_Y_INVERTED_EXT, GL_TRUE, | |
149 GL_NONE, | |
150 }; | |
151 | |
152 int num_fbconfigs; | |
153 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(glXChooseFBConfig( | |
154 x_display_, DefaultScreen(x_display_), fbconfig_attr, &num_fbconfigs)); | |
155 | |
156 if (!glx_fb_configs) { | |
157 DVLOG(1) << "Couldn't get glx configs"; | |
158 return false; | |
159 } | |
160 if (!num_fbconfigs) { | |
161 DVLOG(1) << "Couldn't get at least a glx config"; | |
162 return false; | |
163 } | |
164 | |
165 fb_config_ = glx_fb_configs.get()[0]; | |
166 return true; | |
167 } | |
168 | |
169 } // namespace content | |
OLD | NEW |