Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2010, Google Inc. | 2 * Copyright 2010, Google Inc. |
|
fbarchard
2011/01/24 19:23:09
2011
Tristan Schmelcher 2
2011/01/24 19:43:37
Done.
| |
| 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> | |
|
fbarchard
2011/01/24 19:23:09
is this needed?
Tristan Schmelcher 2
2011/01/24 19:43:37
Yes, it's for memcpy.
| |
| 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) { | |
|
Tim H
2011/01/24 19:57:55
Are i and j typed correctly?
Tristan Schmelcher 2
2011/01/24 20:25:28
Yeah, they are unsigned to prevent compile warning
| |
| 166 for (unsigned j = 0; j < src_width; ++j) { | |
| 167 // Get source pixel. | |
| 168 uint32 src_pixel = *reinterpret_cast<const uint32*>(src_data); | |
| 169 // Initialize dst_pixel to black with src_pixel's transparency. | |
| 170 uint32 dst_pixel = src_pixel & 0xFF000000; | |
| 171 // Get alpha. | |
| 172 uint32 alpha = src_pixel >> 24; | |
| 173 // Convert the blue. | |
| 174 dst_pixel |= (src_pixel & 0xFF) * alpha / 255; | |
|
fbarchard
2011/01/24 19:23:09
Should add rounding
dst_pixel |= ((src_pixel & 0xF
Tristan Schmelcher 2
2011/01/24 19:43:37
Done.
| |
| 175 // Convert the green. | |
| 176 dst_pixel |= (((src_pixel >> 8) & 0xFF) * alpha / 255) << 8; | |
| 177 // Convert the red. | |
| 178 dst_pixel |= (((src_pixel >> 16) & 0xFF) * alpha / 255) << 16; | |
|
fbarchard
2011/01/24 19:23:09
note that this will be slow overall.
would be more
Tristan Schmelcher 2
2011/01/24 19:43:37
Hmm, I will try both and look at the compiled asse
fbarchard
2011/01/24 19:56:19
Using int you have 2 shifts, an AND and OR per cha
| |
| 179 // Store result. | |
| 180 *reinterpret_cast<uint32*>(dst_data) = dst_pixel; | |
| 181 src_data += 4; | |
| 182 dst_data += 4; | |
| 183 } | |
| 184 src_data += src_pitch - src_width * 4; | |
| 185 dst_data += dst_pitch - src_width * 4; | |
| 186 } | |
| 187 } else { | |
| 188 // Just copy the data. | |
| 189 for (unsigned i = 0; i < src_height; ++i) { | |
| 190 memcpy(dst_data, src_data, src_width * 4); | |
| 191 src_data += src_pitch; | |
| 192 dst_data += dst_pitch; | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 cairo_surface_mark_dirty(image_surface_); | |
| 184 | 197 |
| 185 TextureUpdated(); | 198 TextureUpdated(); |
| 186 } | 199 } |
| 187 | 200 |
| 188 // Locks the given mipmap level of this texture for loading from main memory, | 201 // Locks the given mipmap level of this texture for loading from main memory, |
| 189 // and returns a pointer to the buffer. | 202 // and returns a pointer to the buffer. |
| 190 bool TextureCairo::PlatformSpecificLock( | 203 bool TextureCairo::PlatformSpecificLock( |
| 191 int level, void** data, int* pitch, Texture::AccessMode mode) { | 204 int level, void** data, int* pitch, Texture::AccessMode mode) { |
| 192 NOTIMPLEMENTED(); | 205 NOTIMPLEMENTED(); |
| 193 return true; | 206 return true; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 212 | 225 |
| 213 // Returns the implementation-specific texture handle for this texture. | 226 // Returns the implementation-specific texture handle for this texture. |
| 214 void* TextureCairo::GetTextureHandle() const { | 227 void* TextureCairo::GetTextureHandle() const { |
| 215 NOTIMPLEMENTED(); | 228 NOTIMPLEMENTED(); |
| 216 return reinterpret_cast<void*>(NULL); | 229 return reinterpret_cast<void*>(NULL); |
| 217 } | 230 } |
| 218 | 231 |
| 219 } // namespace o2d | 232 } // namespace o2d |
| 220 | 233 |
| 221 } // namespace o3d | 234 } // namespace o3d |
| OLD | NEW |