Chromium Code Reviews| Index: core/cross/cairo/texture_cairo.cc |
| =================================================================== |
| --- core/cross/cairo/texture_cairo.cc (revision 72525) |
| +++ core/cross/cairo/texture_cairo.cc (working copy) |
| @@ -1,5 +1,5 @@ |
| /* |
| - * Copyright 2010, Google Inc. |
| + * Copyright 2011, Google Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| @@ -34,6 +34,9 @@ |
| // Texture Class for handling Cairo Rendering Mode. |
| #include "core/cross/cairo/texture_cairo.h" |
| + |
| +#include <string.h> |
| + |
| #include "core/cross/cairo/renderer_cairo.h" |
| namespace o3d { |
| @@ -62,7 +65,6 @@ |
| TextureCairo::TextureCairo(ServiceLocator* service_locator, |
| cairo_surface_t* image_surface, |
| - cairo_t* image_surface_context, |
| Texture::Format format, |
| int levels, |
| int width, |
| @@ -76,8 +78,7 @@ |
| enable_render_surfaces), |
| renderer_(static_cast<RendererCairo*>( |
| service_locator->GetService<Renderer>())), |
| - image_surface_(image_surface), |
| - image_surface_context_(image_surface_context) { |
| + image_surface_(image_surface) { |
| DLOG(INFO) << "Texture2D Construct"; |
| DCHECK_NE(format, Texture::UNKNOWN_FORMAT); |
| } |
| @@ -91,7 +92,6 @@ |
| bool enable_render_surfaces) { |
| int cairo_format = CairoFormatFromO3DFormat(format); |
| cairo_surface_t* image_surface; |
| - cairo_t* image_surface_context; |
| cairo_status_t status; |
| if (-1 == cairo_format) { |
| DLOG(ERROR) << "Texture format " << format << " not supported by Cairo"; |
| @@ -106,27 +106,15 @@ |
| DLOG(ERROR) << "Error creating Cairo image surface: " << status; |
| goto fail1; |
| } |
| - image_surface_context = cairo_create(image_surface); |
| - status = cairo_status(image_surface_context); |
| - if (CAIRO_STATUS_SUCCESS != status) { |
| - DLOG(ERROR) << "Error creating Cairo image surface draw context: " |
| - << status; |
| - goto fail2; |
| - } |
| - cairo_set_operator(image_surface_context, CAIRO_OPERATOR_SOURCE); |
| - |
| return new TextureCairo(service_locator, |
| image_surface, |
| - image_surface_context, |
| format, |
| levels, |
| width, |
| height, |
| enable_render_surfaces); |
| - fail2: |
| - cairo_destroy(image_surface_context); |
| fail1: |
| cairo_surface_destroy(image_surface); |
| fail0: |
| @@ -140,7 +128,6 @@ |
| } |
| TextureCairo::~TextureCairo() { |
| - cairo_destroy(image_surface_context_); |
| cairo_surface_destroy(image_surface_); |
| renderer_ = NULL; |
| DLOG(INFO) << "Texture2DCairo Destruct"; |
| @@ -152,7 +139,7 @@ |
| unsigned dst_top, |
| unsigned src_width, |
| unsigned src_height, |
| - const void* src_data, |
| + const void* src_data_void, |
| int src_pitch) { |
| DLOG(INFO) << "Texture2DCairo SetRect"; |
| @@ -161,27 +148,48 @@ |
| return; |
| } |
| - // Create image surface to represent the source. |
| - cairo_surface_t* source_image_surface = cairo_image_surface_create_for_data( |
| - const_cast<unsigned char*>( |
| - static_cast<const unsigned char*>(src_data)), |
| - cairo_image_surface_get_format(image_surface_), |
| - src_width, |
| - src_height, |
| - src_pitch); |
| + cairo_surface_flush(image_surface_); |
| - // Set that surface as the source for paint operations to our texture. |
| - cairo_set_source_surface(image_surface_context_, |
| - source_image_surface, |
| - dst_left, |
| - dst_top); |
| + const unsigned char* src_data = reinterpret_cast<const unsigned char*>( |
| + src_data_void); |
| - // Paint to the texture. This copies the data. |
| - cairo_paint(image_surface_context_); |
| + unsigned char* dst_data = cairo_image_surface_get_data(image_surface_); |
| - // Discard our reference to the source surface. |
| - cairo_surface_destroy(source_image_surface); |
| + int dst_pitch = cairo_image_surface_get_stride(image_surface_); |
| + dst_data += dst_top * dst_pitch + dst_left * 4; |
| + |
| + if (ARGB8 == format()) { |
| + // Cairo supports only premultiplied alpha, but we get the images as |
| + // non-premultiplied alpha, so we have to convert. |
| + for (unsigned i = 0; i < src_height; ++i) { |
| + for (unsigned j = 0; j < src_width; ++j) { |
| + // 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.
|
| + // Get alpha. |
| + uint8 alpha = src_data[3]; |
| + // Convert each colour. |
| + for (int i = 0; i < 3; i++) { |
| + 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 +
|
| + } |
| + // Copy alpha. |
| + dst_data[3] = alpha; |
| + src_data += 4; |
| + dst_data += 4; |
| + } |
| + src_data += src_pitch - src_width * 4; |
| + dst_data += dst_pitch - src_width * 4; |
| + } |
| + } else { |
| + // Just copy the data. |
| + for (unsigned i = 0; i < src_height; ++i) { |
| + memcpy(dst_data, src_data, src_width * 4); |
| + src_data += src_pitch; |
| + dst_data += dst_pitch; |
| + } |
| + } |
| + |
| + cairo_surface_mark_dirty(image_surface_); |
| + |
| TextureUpdated(); |
| } |