1 // Copyright 2013 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.
5 #include "ui/gl/gl_image_io_surface.h"
7 #include "ui/gl/gl_bindings.h"
8 #include "ui/gl/gl_context.h"
10 // Note that this must be included after gl_bindings.h to avoid conflicts.
11 #include <OpenGL/CGLIOSurface.h>
16 bool ValidInternalFormat(unsigned internalformat
) {
17 switch (internalformat
) {
26 bool ValidFormat(GpuMemoryBuffer::Format format
) {
28 case GpuMemoryBuffer::R_8
:
29 case GpuMemoryBuffer::BGRA_8888
:
31 case GpuMemoryBuffer::ATC
:
32 case GpuMemoryBuffer::ATCIA
:
33 case GpuMemoryBuffer::DXT1
:
34 case GpuMemoryBuffer::DXT5
:
35 case GpuMemoryBuffer::ETC1
:
36 case GpuMemoryBuffer::RGBA_4444
:
37 case GpuMemoryBuffer::RGBA_8888
:
38 case GpuMemoryBuffer::RGBX_8888
:
39 case GpuMemoryBuffer::YUV_420
:
47 GLenum
TextureFormat(GpuMemoryBuffer::Format format
) {
49 case GpuMemoryBuffer::R_8
:
51 case GpuMemoryBuffer::BGRA_8888
:
53 case GpuMemoryBuffer::ATC
:
54 case GpuMemoryBuffer::ATCIA
:
55 case GpuMemoryBuffer::DXT1
:
56 case GpuMemoryBuffer::DXT5
:
57 case GpuMemoryBuffer::ETC1
:
58 case GpuMemoryBuffer::RGBA_4444
:
59 case GpuMemoryBuffer::RGBA_8888
:
60 case GpuMemoryBuffer::RGBX_8888
:
61 case GpuMemoryBuffer::YUV_420
:
70 GLenum
DataFormat(GpuMemoryBuffer::Format format
) {
72 case GpuMemoryBuffer::R_8
:
74 case GpuMemoryBuffer::BGRA_8888
:
76 case GpuMemoryBuffer::ATC
:
77 case GpuMemoryBuffer::ATCIA
:
78 case GpuMemoryBuffer::DXT1
:
79 case GpuMemoryBuffer::DXT5
:
80 case GpuMemoryBuffer::ETC1
:
81 case GpuMemoryBuffer::RGBA_4444
:
82 case GpuMemoryBuffer::RGBA_8888
:
83 case GpuMemoryBuffer::RGBX_8888
:
84 case GpuMemoryBuffer::YUV_420
:
93 GLenum
DataType(GpuMemoryBuffer::Format format
) {
95 case GpuMemoryBuffer::R_8
:
96 return GL_UNSIGNED_BYTE
;
97 case GpuMemoryBuffer::BGRA_8888
:
98 return GL_UNSIGNED_INT_8_8_8_8_REV
;
99 case GpuMemoryBuffer::ATC
:
100 case GpuMemoryBuffer::ATCIA
:
101 case GpuMemoryBuffer::DXT1
:
102 case GpuMemoryBuffer::DXT5
:
103 case GpuMemoryBuffer::ETC1
:
104 case GpuMemoryBuffer::RGBA_4444
:
105 case GpuMemoryBuffer::RGBA_8888
:
106 case GpuMemoryBuffer::RGBX_8888
:
107 case GpuMemoryBuffer::YUV_420
:
118 GLImageIOSurface::GLImageIOSurface(const gfx::Size
& size
,
119 unsigned internalformat
)
121 internalformat_(internalformat
),
122 format_(GpuMemoryBuffer::RGBA_8888
) {
125 GLImageIOSurface::~GLImageIOSurface() {
126 DCHECK(thread_checker_
.CalledOnValidThread());
127 DCHECK(!io_surface_
);
130 bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface
,
131 GpuMemoryBuffer::Format format
) {
132 DCHECK(thread_checker_
.CalledOnValidThread());
133 DCHECK(!io_surface_
);
135 if (!ValidInternalFormat(internalformat_
)) {
136 LOG(ERROR
) << "Invalid internalformat: " << internalformat_
;
140 if (!ValidFormat(format
)) {
141 LOG(ERROR
) << "Invalid format: " << format
;
146 io_surface_
.reset(io_surface
, base::scoped_policy::RETAIN
);
150 void GLImageIOSurface::Destroy(bool have_context
) {
151 DCHECK(thread_checker_
.CalledOnValidThread());
155 gfx::Size
GLImageIOSurface::GetSize() { return size_
; }
157 unsigned GLImageIOSurface::GetInternalFormat() { return internalformat_
; }
159 bool GLImageIOSurface::BindTexImage(unsigned target
) {
160 DCHECK(thread_checker_
.CalledOnValidThread());
161 if (target
!= GL_TEXTURE_RECTANGLE_ARB
) {
162 // This might be supported in the future. For now, perform strict
163 // validation so we know what's going on.
164 LOG(ERROR
) << "IOSurface requires TEXTURE_RECTANGLE_ARB target";
168 CGLContextObj cgl_context
=
169 static_cast<CGLContextObj
>(GLContext::GetCurrent()->GetHandle());
173 CGLTexImageIOSurface2D(cgl_context
, target
, TextureFormat(format_
),
174 size_
.width(), size_
.height(), DataFormat(format_
),
175 DataType(format_
), io_surface_
.get(), 0);
176 if (cgl_error
!= kCGLNoError
) {
177 LOG(ERROR
) << "Error in CGLTexImageIOSurface2D";
184 bool GLImageIOSurface::CopyTexSubImage(unsigned target
,
190 bool GLImageIOSurface::ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
192 OverlayTransform transform
,
193 const Rect
& bounds_rect
,
194 const RectF
& crop_rect
) {