Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: core/cross/cairo/texture_cairo.cc

Issue 6309007: O2D: Fix graphical artifacting with transparent images caused by using non-pr... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW
« core/cross/cairo/texture_cairo.h ('K') | « core/cross/cairo/texture_cairo.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698