| OLD | NEW |
| (Empty) |
| 1 // Copyright 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 "ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "ui/gl/gl_image_egl.h" | |
| 9 #include "ui/gl/gl_image_linux_dma_buffer.h" | |
| 10 #include "ui/ozone/public/native_pixmap.h" | |
| 11 #include "ui/ozone/public/ozone_platform.h" | |
| 12 #include "ui/ozone/public/surface_factory_ozone.h" | |
| 13 #include "ui/ozone/public/surface_ozone_egl.h" | |
| 14 | |
| 15 namespace ui { | |
| 16 namespace { | |
| 17 class GLImageOzoneNativePixmap : public gfx::GLImageEGL { | |
| 18 public: | |
| 19 explicit GLImageOzoneNativePixmap(const gfx::Size& size) : GLImageEGL(size) {} | |
| 20 | |
| 21 void Destroy(bool have_context) override { | |
| 22 gfx::GLImageEGL::Destroy(have_context); | |
| 23 pixmap_ = nullptr; | |
| 24 } | |
| 25 | |
| 26 bool Initialize(NativePixmap* pixmap) { | |
| 27 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | |
| 28 if (!Initialize(EGL_NATIVE_PIXMAP_KHR, pixmap->GetEGLClientBuffer(), attrs)) | |
| 29 return false; | |
| 30 pixmap_ = pixmap; | |
| 31 return true; | |
| 32 } | |
| 33 | |
| 34 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
| 35 int z_order, | |
| 36 gfx::OverlayTransform transform, | |
| 37 const gfx::Rect& bounds_rect, | |
| 38 const gfx::RectF& crop_rect) override { | |
| 39 return pixmap_ && | |
| 40 pixmap_->ScheduleOverlayPlane(widget, z_order, transform, | |
| 41 bounds_rect, crop_rect); | |
| 42 } | |
| 43 | |
| 44 protected: | |
| 45 ~GLImageOzoneNativePixmap() override {} | |
| 46 | |
| 47 private: | |
| 48 using gfx::GLImageEGL::Initialize; | |
| 49 scoped_refptr<NativePixmap> pixmap_; | |
| 50 }; | |
| 51 | |
| 52 class GLImageOzoneNativePixmapDmaBuf : public gfx::GLImageLinuxDMABuffer { | |
| 53 public: | |
| 54 GLImageOzoneNativePixmapDmaBuf(const gfx::Size& size, unsigned internalformat) | |
| 55 : GLImageLinuxDMABuffer(size, internalformat) {} | |
| 56 | |
| 57 void Destroy(bool have_context) override { | |
| 58 gfx::GLImageLinuxDMABuffer::Destroy(have_context); | |
| 59 pixmap_ = nullptr; | |
| 60 } | |
| 61 | |
| 62 bool Initialize(NativePixmap* pixmap, gfx::GpuMemoryBuffer::Format format) { | |
| 63 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false); | |
| 64 if (!GLImageLinuxDMABuffer::Initialize(handle, format, | |
| 65 pixmap->GetDmaBufPitch())) | |
| 66 return false; | |
| 67 pixmap_ = pixmap; | |
| 68 return true; | |
| 69 } | |
| 70 | |
| 71 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
| 72 int z_order, | |
| 73 gfx::OverlayTransform transform, | |
| 74 const gfx::Rect& bounds_rect, | |
| 75 const gfx::RectF& crop_rect) override { | |
| 76 return pixmap_ && | |
| 77 pixmap_->ScheduleOverlayPlane(widget, z_order, transform, | |
| 78 bounds_rect, crop_rect); | |
| 79 } | |
| 80 | |
| 81 protected: | |
| 82 ~GLImageOzoneNativePixmapDmaBuf() override {} | |
| 83 | |
| 84 private: | |
| 85 scoped_refptr<NativePixmap> pixmap_; | |
| 86 }; | |
| 87 | |
| 88 class GLImageOzoneOverlayOnlyPassThrough : public gfx::GLImage { | |
| 89 public: | |
| 90 GLImageOzoneOverlayOnlyPassThrough(scoped_refptr<NativePixmap> pixmap, | |
| 91 const gfx::Size& size, | |
| 92 unsigned internalformat) | |
| 93 : pixmap_(pixmap), size_(size), internalformat_(internalformat) {} | |
| 94 | |
| 95 void Destroy(bool have_context) override { pixmap_ = nullptr; } | |
| 96 gfx::Size GetSize() override { return size_; } | |
| 97 unsigned GetInternalFormat() override { return internalformat_; } | |
| 98 bool BindTexImage(unsigned target) override { return true; } | |
| 99 void ReleaseTexImage(unsigned target) override {} | |
| 100 bool CopyTexSubImage(unsigned target, | |
| 101 const gfx::Point& offset, | |
| 102 const gfx::Rect& rect) override { | |
| 103 return false; | |
| 104 } | |
| 105 void WillUseTexImage() override {} | |
| 106 void DidUseTexImage() override {} | |
| 107 void WillModifyTexImage() override {} | |
| 108 void DidModifyTexImage() override {} | |
| 109 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
| 110 int z_order, | |
| 111 gfx::OverlayTransform transform, | |
| 112 const gfx::Rect& bounds_rect, | |
| 113 const gfx::RectF& crop_rect) override { | |
| 114 return pixmap_ && | |
| 115 pixmap_->ScheduleOverlayPlane(widget, z_order, transform, | |
| 116 bounds_rect, crop_rect); | |
| 117 } | |
| 118 | |
| 119 protected: | |
| 120 ~GLImageOzoneOverlayOnlyPassThrough() override {} | |
| 121 | |
| 122 private: | |
| 123 scoped_refptr<NativePixmap> pixmap_; | |
| 124 const gfx::Size size_; | |
| 125 unsigned internalformat_; | |
| 126 }; | |
| 127 | |
| 128 SurfaceFactoryOzone::BufferFormat GetOzoneFormatFor( | |
| 129 gfx::GpuMemoryBuffer::Format format) { | |
| 130 switch (format) { | |
| 131 case gfx::GpuMemoryBuffer::BGRA_8888: | |
| 132 return SurfaceFactoryOzone::BGRA_8888; | |
| 133 case gfx::GpuMemoryBuffer::RGBX_8888: | |
| 134 return SurfaceFactoryOzone::RGBX_8888; | |
| 135 case gfx::GpuMemoryBuffer::ATC: | |
| 136 case gfx::GpuMemoryBuffer::ATCIA: | |
| 137 case gfx::GpuMemoryBuffer::DXT1: | |
| 138 case gfx::GpuMemoryBuffer::DXT5: | |
| 139 case gfx::GpuMemoryBuffer::ETC1: | |
| 140 case gfx::GpuMemoryBuffer::R_8: | |
| 141 case gfx::GpuMemoryBuffer::RGBA_4444: | |
| 142 case gfx::GpuMemoryBuffer::RGBA_8888: | |
| 143 case gfx::GpuMemoryBuffer::YUV_420: | |
| 144 NOTREACHED(); | |
| 145 return SurfaceFactoryOzone::BGRA_8888; | |
| 146 } | |
| 147 | |
| 148 NOTREACHED(); | |
| 149 return SurfaceFactoryOzone::BGRA_8888; | |
| 150 } | |
| 151 | |
| 152 SurfaceFactoryOzone::BufferUsage GetOzoneUsageFor( | |
| 153 gfx::GpuMemoryBuffer::Usage usage) { | |
| 154 switch (usage) { | |
| 155 case gfx::GpuMemoryBuffer::MAP: | |
| 156 return SurfaceFactoryOzone::MAP; | |
| 157 case gfx::GpuMemoryBuffer::PERSISTENT_MAP: | |
| 158 return SurfaceFactoryOzone::PERSISTENT_MAP; | |
| 159 case gfx::GpuMemoryBuffer::SCANOUT: | |
| 160 return SurfaceFactoryOzone::SCANOUT; | |
| 161 } | |
| 162 | |
| 163 NOTREACHED(); | |
| 164 return SurfaceFactoryOzone::MAP; | |
| 165 } | |
| 166 | |
| 167 std::pair<uint32_t, uint32_t> GetIndex(gfx::GpuMemoryBufferId id, | |
| 168 int client_id) { | |
| 169 return std::pair<uint32_t, uint32_t>(id, client_id); | |
| 170 } | |
| 171 } // namespace | |
| 172 | |
| 173 GpuMemoryBufferFactoryOzoneNativePixmap:: | |
| 174 GpuMemoryBufferFactoryOzoneNativePixmap() {} | |
| 175 | |
| 176 GpuMemoryBufferFactoryOzoneNativePixmap:: | |
| 177 ~GpuMemoryBufferFactoryOzoneNativePixmap() {} | |
| 178 | |
| 179 bool GpuMemoryBufferFactoryOzoneNativePixmap::CreateGpuMemoryBuffer( | |
| 180 gfx::GpuMemoryBufferId id, | |
| 181 const gfx::Size& size, | |
| 182 gfx::GpuMemoryBuffer::Format format, | |
| 183 gfx::GpuMemoryBuffer::Usage usage, | |
| 184 int client_id, | |
| 185 gfx::PluginWindowHandle surface_handle) { | |
| 186 scoped_refptr<NativePixmap> pixmap = | |
| 187 OzonePlatform::GetInstance() | |
| 188 ->GetSurfaceFactoryOzone() | |
| 189 ->CreateNativePixmap(surface_handle, size, GetOzoneFormatFor(format), | |
| 190 GetOzoneUsageFor(usage)); | |
| 191 if (!pixmap.get()) { | |
| 192 LOG(ERROR) << "Failed to create pixmap " << size.width() << "x" | |
| 193 << size.height() << " format " << format << ", usage " << usage; | |
| 194 return false; | |
| 195 } | |
| 196 base::AutoLock lock(native_pixmap_map_lock_); | |
| 197 native_pixmap_map_[GetIndex(id, client_id)] = pixmap; | |
| 198 return true; | |
| 199 } | |
| 200 | |
| 201 void GpuMemoryBufferFactoryOzoneNativePixmap::DestroyGpuMemoryBuffer( | |
| 202 gfx::GpuMemoryBufferId id, | |
| 203 int client_id) { | |
| 204 base::AutoLock lock(native_pixmap_map_lock_); | |
| 205 native_pixmap_map_.erase(GetIndex(id, client_id)); | |
| 206 } | |
| 207 | |
| 208 scoped_refptr<gfx::GLImage> | |
| 209 GpuMemoryBufferFactoryOzoneNativePixmap::CreateImageForGpuMemoryBuffer( | |
| 210 gfx::GpuMemoryBufferId id, | |
| 211 const gfx::Size& size, | |
| 212 gfx::GpuMemoryBuffer::Format format, | |
| 213 unsigned internalformat, | |
| 214 int client_id) { | |
| 215 NativePixmap* pixmap = nullptr; | |
| 216 { | |
| 217 base::AutoLock lock(native_pixmap_map_lock_); | |
| 218 BufferToPixmapMap::iterator it = | |
| 219 native_pixmap_map_.find(GetIndex(id, client_id)); | |
| 220 if (it == native_pixmap_map_.end()) { | |
| 221 return scoped_refptr<gfx::GLImage>(); | |
| 222 } | |
| 223 pixmap = it->second.get(); | |
| 224 } | |
| 225 return CreateImageForPixmap(pixmap, size, format, internalformat); | |
| 226 } | |
| 227 | |
| 228 scoped_refptr<gfx::GLImage> | |
| 229 GpuMemoryBufferFactoryOzoneNativePixmap::CreateImageForPixmap( | |
| 230 scoped_refptr<NativePixmap> pixmap, | |
| 231 const gfx::Size& size, | |
| 232 gfx::GpuMemoryBuffer::Format format, | |
| 233 unsigned internalformat) { | |
| 234 if (!pixmap.get()) { | |
| 235 NOTREACHED(); | |
| 236 return scoped_refptr<gfx::GLImage>(); | |
| 237 } | |
| 238 | |
| 239 if (pixmap->GetEGLClientBuffer()) { | |
| 240 scoped_refptr<GLImageOzoneNativePixmap> image = | |
| 241 new GLImageOzoneNativePixmap(size); | |
| 242 if (!image->Initialize(pixmap.get())) { | |
| 243 return scoped_refptr<gfx::GLImage>(); | |
| 244 } | |
| 245 return image; | |
| 246 } | |
| 247 if (pixmap->GetDmaBufFd() > 0) { | |
| 248 scoped_refptr<GLImageOzoneNativePixmapDmaBuf> image = | |
| 249 new GLImageOzoneNativePixmapDmaBuf(size, internalformat); | |
| 250 if (!image->Initialize(pixmap.get(), format)) { | |
| 251 return scoped_refptr<gfx::GLImage>(); | |
| 252 } | |
| 253 return image; | |
| 254 } | |
| 255 return new GLImageOzoneOverlayOnlyPassThrough(pixmap, size, internalformat); | |
| 256 } | |
| 257 | |
| 258 } // namespace ui | |
| OLD | NEW |