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_drm.h" |
| 6 #include "content/common/gpu/media/vaapi_wrapper.h" |
| 7 #include "third_party/libva/va/drm/va_drm.h" |
| 8 #include "third_party/libva/va/va_drmcommon.h" |
| 9 #include "ui/gl/gl_bindings.h" |
| 10 #include "ui/gl/gl_image.h" |
| 11 #include "ui/gl/gl_image_egl.h" |
| 12 #include "ui/gl/scoped_binders.h" |
| 13 #include "ui/ozone/public/native_pixmap.h" |
| 14 #include "ui/ozone/public/ozone_platform.h" |
| 15 #include "ui/ozone/public/surface_factory_ozone.h" |
| 16 |
| 17 namespace content { |
| 18 |
| 19 class DrmPicture : public VaapiPictureProvider::Picture { |
| 20 public: |
| 21 DrmPicture(scoped_refptr<VaapiWrapper> vaapi_wrapper, |
| 22 const base::Callback<bool(void)> make_context_current, |
| 23 int32 picture_buffer_id, |
| 24 uint32 texture_id, |
| 25 const gfx::Size& size) |
| 26 : Picture(picture_buffer_id, texture_id, size), |
| 27 vaapi_wrapper_(vaapi_wrapper), |
| 28 make_context_current_(make_context_current) {} |
| 29 |
| 30 virtual ~DrmPicture(); |
| 31 |
| 32 bool Initialize() override; |
| 33 |
| 34 virtual bool DownloadFromSurface(VASurfaceID va_surface_id, |
| 35 const gfx::Size& surface_size) override; |
| 36 |
| 37 private: |
| 38 scoped_refptr<VaapiWrapper> vaapi_wrapper_; |
| 39 base::Callback<bool(void)> make_context_current_; |
| 40 scoped_refptr<VASurface> va_surface_; |
| 41 scoped_refptr<ui::NativePixmap> pixmap_; |
| 42 scoped_refptr<gfx::GLImageEGL> gl_image_; |
| 43 |
| 44 DISALLOW_COPY_AND_ASSIGN(DrmPicture); |
| 45 }; |
| 46 |
| 47 DrmPicture::~DrmPicture() { |
| 48 if (gl_image_.get() && make_context_current_.Run()) { |
| 49 // ReleaseTexImage on a GLImageEGL does nothing, to deassociate |
| 50 // the renderer's texture from the image, just set the storage |
| 51 // of that texture to NULL |
| 52 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id()); |
| 53 glTexImage2D(GL_TEXTURE_2D, |
| 54 0, |
| 55 GL_RGBA, |
| 56 size().width(), |
| 57 size().height(), |
| 58 0, |
| 59 GL_RGBA, |
| 60 GL_UNSIGNED_BYTE, |
| 61 NULL); |
| 62 |
| 63 gl_image_->Destroy(true); |
| 64 |
| 65 DCHECK_EQ(glGetError(), GL_NO_ERROR); |
| 66 } |
| 67 } |
| 68 |
| 69 bool DrmPicture::Initialize() { |
| 70 VASurfaceAttrib va_attribs[2]; |
| 71 VASurfaceAttribExternalBuffers va_attrib_extbuf; |
| 72 |
| 73 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); |
| 74 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); |
| 75 |
| 76 pixmap_ = |
| 77 factory->CreateNativePixmap(size(), ui::SurfaceFactoryOzone::RGBA_8888); |
| 78 if (!pixmap_.get()) |
| 79 return false; |
| 80 |
| 81 int dmabuf_fd = pixmap_->GetDmaBufFd(); |
| 82 if (dmabuf_fd < 0) |
| 83 return false; |
| 84 |
| 85 va_attrib_extbuf.pixel_format = VA_FOURCC_BGRX; |
| 86 va_attrib_extbuf.width = size().width(); |
| 87 va_attrib_extbuf.height = size().height(); |
| 88 va_attrib_extbuf.data_size = size().height() * pixmap_->GetDmaBufPitch(); |
| 89 va_attrib_extbuf.num_planes = 1; |
| 90 va_attrib_extbuf.pitches[0] = pixmap_->GetDmaBufPitch(); |
| 91 va_attrib_extbuf.offsets[0] = 0; |
| 92 va_attrib_extbuf.buffers = reinterpret_cast<unsigned long*>(&dmabuf_fd); |
| 93 va_attrib_extbuf.num_buffers = 1; |
| 94 va_attrib_extbuf.flags = 0; |
| 95 va_attrib_extbuf.private_data = NULL; |
| 96 |
| 97 va_attribs[0].type = VASurfaceAttribMemoryType; |
| 98 va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; |
| 99 va_attribs[0].value.type = VAGenericValueTypeInteger; |
| 100 va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; |
| 101 |
| 102 va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor; |
| 103 va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; |
| 104 va_attribs[1].value.type = VAGenericValueTypePointer; |
| 105 va_attribs[1].value.value.p = &va_attrib_extbuf; |
| 106 |
| 107 va_surface_ = vaapi_wrapper_->CreateUnownedSurface( |
| 108 VA_RT_FORMAT_RGB32, size(), va_attribs, arraysize(va_attribs)); |
| 109 if (!va_surface_.get()) |
| 110 return false; |
| 111 |
| 112 if (!make_context_current_.Run()) |
| 113 return false; |
| 114 |
| 115 gl_image_ = new gfx::GLImageEGL(size()); |
| 116 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
| 117 if (!gl_image_->Initialize( |
| 118 EGL_NATIVE_PIXMAP_KHR, pixmap_->GetEGLClientBuffer(), attrs)) |
| 119 return false; |
| 120 |
| 121 return true; |
| 122 } |
| 123 |
| 124 bool DrmPicture::DownloadFromSurface(VASurfaceID va_surface_id, |
| 125 const gfx::Size& surface_size) { |
| 126 if (!vaapi_wrapper_->BlitSurface( |
| 127 va_surface_id, surface_size, va_surface_->id(), va_surface_->size())) |
| 128 return false; |
| 129 |
| 130 if (!make_context_current_.Run()) |
| 131 return false; |
| 132 |
| 133 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id()); |
| 134 return gl_image_->BindTexImage(GL_TEXTURE_2D); |
| 135 } |
| 136 |
| 137 DrmVaapiPictureProvider::DrmVaapiPictureProvider( |
| 138 scoped_refptr<VaapiWrapper> vaapi_wrapper, |
| 139 const base::Callback<bool(void)> make_context_current) |
| 140 : make_context_current_(make_context_current), |
| 141 vaapi_wrapper_(vaapi_wrapper) { |
| 142 } |
| 143 |
| 144 DrmVaapiPictureProvider::~DrmVaapiPictureProvider() { |
| 145 } |
| 146 |
| 147 linked_ptr<VaapiPictureProvider::Picture> |
| 148 DrmVaapiPictureProvider::AllocatePicture(int32 picture_buffer_id, |
| 149 uint32 texture_id, |
| 150 const gfx::Size& size) { |
| 151 return linked_ptr<VaapiPictureProvider::Picture>( |
| 152 new DrmPicture(vaapi_wrapper_, |
| 153 make_context_current_, |
| 154 picture_buffer_id, |
| 155 texture_id, |
| 156 size)); |
| 157 } |
| 158 |
| 159 bool DrmVaapiPictureProvider::Initialize() { |
| 160 return true; |
| 161 } |
| 162 |
| 163 } // namespace |
OLD | NEW |