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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « core/cross/cairo/texture_cairo.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,49 @@
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 architecture (e.g., x86). It works
+ // for RGBA or BGRA where alpha is in byte 3.
+ // 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;
+ }
+ // 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();
}
« no previous file with comments | « core/cross/cairo/texture_cairo.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698