Add ICU message format support
[chromium-blink-merge.git] / ui / gl / gl_image_io_surface.mm
blob2044f3775a16590370ee323eac853eb007aaf98f
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 <map>
9 #include "base/lazy_instance.h"
10 #include "base/mac/foundation_util.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_context.h"
14 // Note that this must be included after gl_bindings.h to avoid conflicts.
15 #include <OpenGL/CGLIOSurface.h>
16 #include <Quartz/Quartz.h>
18 namespace gfx {
19 namespace {
21 typedef std::map<gfx::AcceleratedWidget,CALayer*> WidgetToLayerMap;
22 base::LazyInstance<WidgetToLayerMap> g_widget_to_layer_map;
24 bool ValidInternalFormat(unsigned internalformat) {
25   switch (internalformat) {
26     case GL_R8:
27     case GL_BGRA_EXT:
28       return true;
29     default:
30       return false;
31   }
34 bool ValidFormat(BufferFormat format) {
35   switch (format) {
36     case BufferFormat::R_8:
37     case BufferFormat::BGRA_8888:
38       return true;
39     case BufferFormat::ATC:
40     case BufferFormat::ATCIA:
41     case BufferFormat::DXT1:
42     case BufferFormat::DXT5:
43     case BufferFormat::ETC1:
44     case BufferFormat::RGBA_4444:
45     case BufferFormat::RGBA_8888:
46     case BufferFormat::RGBX_8888:
47     case BufferFormat::YUV_420:
48       return false;
49   }
51   NOTREACHED();
52   return false;
55 GLenum TextureFormat(BufferFormat format) {
56   switch (format) {
57     case BufferFormat::R_8:
58       return GL_RED;
59     case BufferFormat::BGRA_8888:
60       return GL_RGBA;
61     case BufferFormat::ATC:
62     case BufferFormat::ATCIA:
63     case BufferFormat::DXT1:
64     case BufferFormat::DXT5:
65     case BufferFormat::ETC1:
66     case BufferFormat::RGBA_4444:
67     case BufferFormat::RGBA_8888:
68     case BufferFormat::RGBX_8888:
69     case BufferFormat::YUV_420:
70       NOTREACHED();
71       return 0;
72   }
74   NOTREACHED();
75   return 0;
78 GLenum DataFormat(BufferFormat format) {
79   switch (format) {
80     case BufferFormat::R_8:
81       return GL_RED;
82     case BufferFormat::BGRA_8888:
83       return GL_BGRA;
84     case BufferFormat::ATC:
85     case BufferFormat::ATCIA:
86     case BufferFormat::DXT1:
87     case BufferFormat::DXT5:
88     case BufferFormat::ETC1:
89     case BufferFormat::RGBA_4444:
90     case BufferFormat::RGBA_8888:
91     case BufferFormat::RGBX_8888:
92     case BufferFormat::YUV_420:
93       NOTREACHED();
94       return 0;
95   }
97   NOTREACHED();
98   return 0;
101 GLenum DataType(BufferFormat format) {
102   switch (format) {
103     case BufferFormat::R_8:
104       return GL_UNSIGNED_BYTE;
105     case BufferFormat::BGRA_8888:
106       return GL_UNSIGNED_INT_8_8_8_8_REV;
107     case BufferFormat::ATC:
108     case BufferFormat::ATCIA:
109     case BufferFormat::DXT1:
110     case BufferFormat::DXT5:
111     case BufferFormat::ETC1:
112     case BufferFormat::RGBA_4444:
113     case BufferFormat::RGBA_8888:
114     case BufferFormat::RGBX_8888:
115     case BufferFormat::YUV_420:
116       NOTREACHED();
117       return 0;
118   }
120   NOTREACHED();
121   return 0;
124 }  // namespace
126 GLImageIOSurface::GLImageIOSurface(const gfx::Size& size,
127                                    unsigned internalformat)
128     : size_(size),
129       internalformat_(internalformat),
130       format_(BufferFormat::RGBA_8888) {}
132 GLImageIOSurface::~GLImageIOSurface() {
133   DCHECK(thread_checker_.CalledOnValidThread());
134   DCHECK(!io_surface_);
137 bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface,
138                                   BufferFormat format) {
139   DCHECK(thread_checker_.CalledOnValidThread());
140   DCHECK(!io_surface_);
142   if (!ValidInternalFormat(internalformat_)) {
143     LOG(ERROR) << "Invalid internalformat: " << internalformat_;
144     return false;
145   }
147   if (!ValidFormat(format)) {
148     LOG(ERROR) << "Invalid format: " << static_cast<int>(format);
149     return false;
150   }
152   format_ = format;
153   io_surface_.reset(io_surface, base::scoped_policy::RETAIN);
154   return true;
157 void GLImageIOSurface::Destroy(bool have_context) {
158   DCHECK(thread_checker_.CalledOnValidThread());
159   io_surface_.reset();
162 gfx::Size GLImageIOSurface::GetSize() { return size_; }
164 unsigned GLImageIOSurface::GetInternalFormat() { return internalformat_; }
166 bool GLImageIOSurface::BindTexImage(unsigned target) {
167   DCHECK(thread_checker_.CalledOnValidThread());
168   if (target != GL_TEXTURE_RECTANGLE_ARB) {
169     // This might be supported in the future. For now, perform strict
170     // validation so we know what's going on.
171     LOG(ERROR) << "IOSurface requires TEXTURE_RECTANGLE_ARB target";
172     return false;
173   }
175   CGLContextObj cgl_context =
176       static_cast<CGLContextObj>(GLContext::GetCurrent()->GetHandle());
178   DCHECK(io_surface_);
179   CGLError cgl_error =
180       CGLTexImageIOSurface2D(cgl_context, target, TextureFormat(format_),
181                              size_.width(), size_.height(), DataFormat(format_),
182                              DataType(format_), io_surface_.get(), 0);
183   if (cgl_error != kCGLNoError) {
184     LOG(ERROR) << "Error in CGLTexImageIOSurface2D";
185     return false;
186   }
188   return true;
191 bool GLImageIOSurface::CopyTexSubImage(unsigned target,
192                                        const Point& offset,
193                                        const Rect& rect) {
194   return false;
197 bool GLImageIOSurface::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
198                                             int z_order,
199                                             OverlayTransform transform,
200                                             const Rect& bounds_rect,
201                                             const RectF& crop_rect) {
202   // Only simple overlay planes are currently supported.
203   DCHECK_EQ(0, z_order);
204   DCHECK_EQ(gfx::RectF(0, 0, 1, 1).ToString(), crop_rect.ToString());
205   DCHECK_EQ(gfx::OVERLAY_TRANSFORM_NONE, transform);
207   // Convert the phony widget to the appropriate CALayer.
208   auto found = g_widget_to_layer_map.Pointer()->find(widget);
209   if (found == g_widget_to_layer_map.Pointer()->end())
210     return false;
211   CALayer* layer = found->second;
213   // Also note that transactions are not disabled. The caller must ensure that
214   // all changes to the CALayer tree happen atomically.
215   [layer setContents:static_cast<id>(io_surface_.get())];
216   [layer setFrame:bounds_rect.ToCGRect()];
217   return true;
220 // static
221 void GLImageIOSurface::SetLayerForWidget(
222     gfx::AcceleratedWidget widget, CALayer* layer) {
223   if (layer)
224     g_widget_to_layer_map.Pointer()->insert(std::make_pair(widget, layer));
225   else
226     g_widget_to_layer_map.Pointer()->erase(widget);
229 }  // namespace gfx