OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2010, Google Inc. | 2 * Copyright 2011, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * * Redistributions in binary form must reproduce the above | 11 * * Redistributions in binary form must reproduce the above |
12 * copyright notice, this list of conditions and the following disclaimer | 12 * copyright notice, this list of conditions and the following disclaimer |
(...skipping 14 matching lines...) Expand all Loading... | |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 | 32 |
33 // Implementations of the abstract Texture2D. | 33 // Implementations of the abstract Texture2D. |
34 // Texture Class for handling Cairo Rendering Mode. | 34 // Texture Class for handling Cairo Rendering Mode. |
35 | 35 |
36 #include "core/cross/cairo/texture_cairo.h" | 36 #include "core/cross/cairo/texture_cairo.h" |
37 | |
38 #include <string.h> | |
39 | |
37 #include "core/cross/cairo/renderer_cairo.h" | 40 #include "core/cross/cairo/renderer_cairo.h" |
38 | 41 |
39 namespace o3d { | 42 namespace o3d { |
40 | 43 |
41 namespace { | 44 namespace { |
42 | 45 |
43 Texture::RGBASwizzleIndices g_gl_abgr32f_swizzle_indices = {0, 1, 2, 3}; | 46 Texture::RGBASwizzleIndices g_gl_abgr32f_swizzle_indices = {0, 1, 2, 3}; |
44 | 47 |
45 } // anonymous namespace. | 48 } // anonymous namespace. |
46 | 49 |
47 namespace o2d { | 50 namespace o2d { |
48 | 51 |
49 static int CairoFormatFromO3DFormat( | 52 static int CairoFormatFromO3DFormat( |
50 Texture::Format format) { | 53 Texture::Format format) { |
51 switch (format) { | 54 switch (format) { |
52 case Texture::ARGB8: | 55 case Texture::ARGB8: |
53 return CAIRO_FORMAT_ARGB32; | 56 return CAIRO_FORMAT_ARGB32; |
54 case Texture::XRGB8: | 57 case Texture::XRGB8: |
55 return CAIRO_FORMAT_RGB24; | 58 return CAIRO_FORMAT_RGB24; |
56 default: | 59 default: |
57 return -1; | 60 return -1; |
58 } | 61 } |
59 // Cairo also supports two other pure-alpha formats, but we don't expose those | 62 // Cairo also supports two other pure-alpha formats, but we don't expose those |
60 // capabilities. | 63 // capabilities. |
61 } | 64 } |
62 | 65 |
63 TextureCairo::TextureCairo(ServiceLocator* service_locator, | 66 TextureCairo::TextureCairo(ServiceLocator* service_locator, |
64 cairo_surface_t* image_surface, | 67 cairo_surface_t* image_surface, |
65 cairo_t* image_surface_context, | |
66 Texture::Format format, | 68 Texture::Format format, |
67 int levels, | 69 int levels, |
68 int width, | 70 int width, |
69 int height, | 71 int height, |
70 bool enable_render_surfaces) | 72 bool enable_render_surfaces) |
71 : Texture2D(service_locator, | 73 : Texture2D(service_locator, |
72 width, | 74 width, |
73 height, | 75 height, |
74 format, | 76 format, |
75 levels, | 77 levels, |
76 enable_render_surfaces), | 78 enable_render_surfaces), |
77 renderer_(static_cast<RendererCairo*>( | 79 renderer_(static_cast<RendererCairo*>( |
78 service_locator->GetService<Renderer>())), | 80 service_locator->GetService<Renderer>())), |
79 image_surface_(image_surface), | 81 image_surface_(image_surface) { |
80 image_surface_context_(image_surface_context) { | |
81 DLOG(INFO) << "Texture2D Construct"; | 82 DLOG(INFO) << "Texture2D Construct"; |
82 DCHECK_NE(format, Texture::UNKNOWN_FORMAT); | 83 DCHECK_NE(format, Texture::UNKNOWN_FORMAT); |
83 } | 84 } |
84 | 85 |
85 // Creates a new texture object from scratch. | 86 // Creates a new texture object from scratch. |
86 TextureCairo* TextureCairo::Create(ServiceLocator* service_locator, | 87 TextureCairo* TextureCairo::Create(ServiceLocator* service_locator, |
87 Texture::Format format, | 88 Texture::Format format, |
88 int levels, | 89 int levels, |
89 int width, | 90 int width, |
90 int height, | 91 int height, |
91 bool enable_render_surfaces) { | 92 bool enable_render_surfaces) { |
92 int cairo_format = CairoFormatFromO3DFormat(format); | 93 int cairo_format = CairoFormatFromO3DFormat(format); |
93 cairo_surface_t* image_surface; | 94 cairo_surface_t* image_surface; |
94 cairo_t* image_surface_context; | |
95 cairo_status_t status; | 95 cairo_status_t status; |
96 if (-1 == cairo_format) { | 96 if (-1 == cairo_format) { |
97 DLOG(ERROR) << "Texture format " << format << " not supported by Cairo"; | 97 DLOG(ERROR) << "Texture format " << format << " not supported by Cairo"; |
98 goto fail0; | 98 goto fail0; |
99 } | 99 } |
100 image_surface = cairo_image_surface_create( | 100 image_surface = cairo_image_surface_create( |
101 static_cast<cairo_format_t>(cairo_format), | 101 static_cast<cairo_format_t>(cairo_format), |
102 width, | 102 width, |
103 height); | 103 height); |
104 status = cairo_surface_status(image_surface); | 104 status = cairo_surface_status(image_surface); |
105 if (CAIRO_STATUS_SUCCESS != status) { | 105 if (CAIRO_STATUS_SUCCESS != status) { |
106 DLOG(ERROR) << "Error creating Cairo image surface: " << status; | 106 DLOG(ERROR) << "Error creating Cairo image surface: " << status; |
107 goto fail1; | 107 goto fail1; |
108 } | 108 } |
109 image_surface_context = cairo_create(image_surface); | |
110 status = cairo_status(image_surface_context); | |
111 if (CAIRO_STATUS_SUCCESS != status) { | |
112 DLOG(ERROR) << "Error creating Cairo image surface draw context: " | |
113 << status; | |
114 goto fail2; | |
115 } | |
116 | |
117 cairo_set_operator(image_surface_context, CAIRO_OPERATOR_SOURCE); | |
118 | 109 |
119 return new TextureCairo(service_locator, | 110 return new TextureCairo(service_locator, |
120 image_surface, | 111 image_surface, |
121 image_surface_context, | |
122 format, | 112 format, |
123 levels, | 113 levels, |
124 width, | 114 width, |
125 height, | 115 height, |
126 enable_render_surfaces); | 116 enable_render_surfaces); |
127 | 117 |
128 fail2: | |
129 cairo_destroy(image_surface_context); | |
130 fail1: | 118 fail1: |
131 cairo_surface_destroy(image_surface); | 119 cairo_surface_destroy(image_surface); |
132 fail0: | 120 fail0: |
133 return NULL; | 121 return NULL; |
134 } | 122 } |
135 | 123 |
136 // In 2D: is not really used | 124 // In 2D: is not really used |
137 const Texture::RGBASwizzleIndices& TextureCairo::GetABGR32FSwizzleIndices() { | 125 const Texture::RGBASwizzleIndices& TextureCairo::GetABGR32FSwizzleIndices() { |
138 NOTIMPLEMENTED(); | 126 NOTIMPLEMENTED(); |
139 return g_gl_abgr32f_swizzle_indices; | 127 return g_gl_abgr32f_swizzle_indices; |
140 } | 128 } |
141 | 129 |
142 TextureCairo::~TextureCairo() { | 130 TextureCairo::~TextureCairo() { |
143 cairo_destroy(image_surface_context_); | |
144 cairo_surface_destroy(image_surface_); | 131 cairo_surface_destroy(image_surface_); |
145 renderer_ = NULL; | 132 renderer_ = NULL; |
146 DLOG(INFO) << "Texture2DCairo Destruct"; | 133 DLOG(INFO) << "Texture2DCairo Destruct"; |
147 } | 134 } |
148 | 135 |
149 // Set the image data to the renderer | 136 // Set the image data to the renderer |
150 void TextureCairo::SetRect(int level, | 137 void TextureCairo::SetRect(int level, |
151 unsigned dst_left, | 138 unsigned dst_left, |
152 unsigned dst_top, | 139 unsigned dst_top, |
153 unsigned src_width, | 140 unsigned src_width, |
154 unsigned src_height, | 141 unsigned src_height, |
155 const void* src_data, | 142 const void* src_data_void, |
156 int src_pitch) { | 143 int src_pitch) { |
157 DLOG(INFO) << "Texture2DCairo SetRect"; | 144 DLOG(INFO) << "Texture2DCairo SetRect"; |
158 | 145 |
159 if (0 != level) { | 146 if (0 != level) { |
160 // Cairo does not support/need mip-maps. | 147 // Cairo does not support/need mip-maps. |
161 return; | 148 return; |
162 } | 149 } |
163 | 150 |
164 // Create image surface to represent the source. | 151 cairo_surface_flush(image_surface_); |
165 cairo_surface_t* source_image_surface = cairo_image_surface_create_for_data( | |
166 const_cast<unsigned char*>( | |
167 static_cast<const unsigned char*>(src_data)), | |
168 cairo_image_surface_get_format(image_surface_), | |
169 src_width, | |
170 src_height, | |
171 src_pitch); | |
172 | 152 |
173 // Set that surface as the source for paint operations to our texture. | 153 const unsigned char* src_data = reinterpret_cast<const unsigned char*>( |
174 cairo_set_source_surface(image_surface_context_, | 154 src_data_void); |
175 source_image_surface, | |
176 dst_left, | |
177 dst_top); | |
178 | 155 |
179 // Paint to the texture. This copies the data. | 156 unsigned char* dst_data = cairo_image_surface_get_data(image_surface_); |
180 cairo_paint(image_surface_context_); | |
181 | 157 |
182 // Discard our reference to the source surface. | 158 int dst_pitch = cairo_image_surface_get_stride(image_surface_); |
183 cairo_surface_destroy(source_image_surface); | 159 |
160 dst_data += dst_top * dst_pitch + dst_left * 4; | |
161 | |
162 if (ARGB8 == format()) { | |
163 // Cairo supports only premultiplied alpha, but we get the images as | |
164 // non-premultiplied alpha, so we have to convert. | |
165 for (unsigned i = 0; i < src_height; ++i) { | |
166 for (unsigned j = 0; j < src_width; ++j) { | |
167 // NOTE: This assumes a little-endian anchitecture (e.g., x86). | |
fbarchard
2011/01/26 00:32:48
This works for RGBA or BGRA where alpha is in byte
Tristan Schmelcher 2
2011/01/26 01:12:02
Done.
| |
168 // Get alpha. | |
169 uint8 alpha = src_data[3]; | |
170 // Convert each colour. | |
171 for (int i = 0; i < 3; i++) { | |
172 dst_data[i] = (src_data[i] * alpha + 128U) / 255U; | |
fbarchard
2011/01/25 23:19:22
unroll loop
dst_data[0] = (src_data[0] * alpha +
| |
173 } | |
174 // Copy alpha. | |
175 dst_data[3] = alpha; | |
176 src_data += 4; | |
177 dst_data += 4; | |
178 } | |
179 src_data += src_pitch - src_width * 4; | |
180 dst_data += dst_pitch - src_width * 4; | |
181 } | |
182 } else { | |
183 // Just copy the data. | |
184 for (unsigned i = 0; i < src_height; ++i) { | |
185 memcpy(dst_data, src_data, src_width * 4); | |
186 src_data += src_pitch; | |
187 dst_data += dst_pitch; | |
188 } | |
189 } | |
190 | |
191 cairo_surface_mark_dirty(image_surface_); | |
184 | 192 |
185 TextureUpdated(); | 193 TextureUpdated(); |
186 } | 194 } |
187 | 195 |
188 // Locks the given mipmap level of this texture for loading from main memory, | 196 // Locks the given mipmap level of this texture for loading from main memory, |
189 // and returns a pointer to the buffer. | 197 // and returns a pointer to the buffer. |
190 bool TextureCairo::PlatformSpecificLock( | 198 bool TextureCairo::PlatformSpecificLock( |
191 int level, void** data, int* pitch, Texture::AccessMode mode) { | 199 int level, void** data, int* pitch, Texture::AccessMode mode) { |
192 NOTIMPLEMENTED(); | 200 NOTIMPLEMENTED(); |
193 return true; | 201 return true; |
(...skipping 18 matching lines...) Expand all Loading... | |
212 | 220 |
213 // Returns the implementation-specific texture handle for this texture. | 221 // Returns the implementation-specific texture handle for this texture. |
214 void* TextureCairo::GetTextureHandle() const { | 222 void* TextureCairo::GetTextureHandle() const { |
215 NOTIMPLEMENTED(); | 223 NOTIMPLEMENTED(); |
216 return reinterpret_cast<void*>(NULL); | 224 return reinterpret_cast<void*>(NULL); |
217 } | 225 } |
218 | 226 |
219 } // namespace o2d | 227 } // namespace o2d |
220 | 228 |
221 } // namespace o3d | 229 } // namespace o3d |
OLD | NEW |