diff options
Diffstat (limited to 'webkit/glue/plugins/pepper_graphics_2d.cc')
-rw-r--r-- | webkit/glue/plugins/pepper_graphics_2d.cc | 106 |
1 files changed, 88 insertions, 18 deletions
diff --git a/webkit/glue/plugins/pepper_graphics_2d.cc b/webkit/glue/plugins/pepper_graphics_2d.cc index 864b138d..a75da85 100644 --- a/webkit/glue/plugins/pepper_graphics_2d.cc +++ b/webkit/glue/plugins/pepper_graphics_2d.cc @@ -63,6 +63,53 @@ bool ValidateAndConvertRect(const PP_Rect* rect, return true; } +// Converts BGRA <-> RGBA. +void ConvertBetweenBGRAandRGBA(const uint32_t* input, + int pixel_length, + uint32_t* output) { + for (int i = 0; i < pixel_length; i++) { + const unsigned char* pixel_in = + reinterpret_cast<const unsigned char*>(&input[i]); + unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); + pixel_out[0] = pixel_in[2]; + pixel_out[1] = pixel_in[1]; + pixel_out[2] = pixel_in[0]; + pixel_out[3] = pixel_in[3]; + } +} + +// Converts ImageData from PP_IMAGEDATAFORMAT_BGRA_PREMUL to +// PP_IMAGEDATAFORMAT_RGBA_PREMUL, or reverse. +void ConvertImageData(ImageData* src_image, const SkIRect& src_rect, + ImageData* dest_image, const SkRect& dest_rect) { + DCHECK(src_image->format() != dest_image->format()); + DCHECK(ImageData::IsImageDataFormatSupported(src_image->format())); + DCHECK(ImageData::IsImageDataFormatSupported(dest_image->format())); + + const SkBitmap* src_bitmap = src_image->GetMappedBitmap(); + const SkBitmap* dest_bitmap = dest_image->GetMappedBitmap(); + if (src_rect.width() == src_image->width() && + dest_rect.width() == dest_image->width()) { + // Fast path if the full line needs to be converted. + ConvertBetweenBGRAandRGBA( + src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), + static_cast<int>(src_rect.fTop)), + src_rect.width() * src_rect.height(), + dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), + static_cast<int>(dest_rect.fTop))); + } else { + // Slow path where we convert line by line. + for (int y = 0; y < src_rect.height(); y++) { + ConvertBetweenBGRAandRGBA( + src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), + static_cast<int>(src_rect.fTop + y)), + src_rect.width(), + dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), + static_cast<int>(dest_rect.fTop + y))); + } + } +} + PP_Resource Create(PP_Module module_id, const PP_Size* size, bool is_always_opaque) { @@ -186,8 +233,8 @@ const PPB_Graphics2D* Graphics2D::GetInterface() { bool Graphics2D::Init(int width, int height, bool is_always_opaque) { // The underlying ImageData will validate the dimensions. image_data_ = new ImageData(module()); - if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || - !image_data_->Map()) { + if (!image_data_->Init(ImageData::GetNativeImageDataFormat(), width, height, + true) || !image_data_->Map()) { image_data_ = NULL; return false; } @@ -265,7 +312,7 @@ void Graphics2D::ReplaceContents(PP_Resource image_data) { Resource::GetAs<ImageData>(image_data)); if (!image_resource) return; - if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) + if (!ImageData::IsImageDataFormatSupported(image_resource->format())) return; if (image_resource->width() != image_data_->width() || @@ -337,7 +384,7 @@ bool Graphics2D::ReadImageData(PP_Resource image, scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); if (!image_resource) return false; - if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) + if (!ImageData::IsImageDataFormatSupported(image_resource->format())) return false; // Must be in the right format. // Validate the bitmap position. @@ -355,7 +402,6 @@ bool Graphics2D::ReadImageData(PP_Resource image, ImageDataAutoMapper auto_mapper(image_resource); if (!auto_mapper.is_valid()) return false; - skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); SkIRect src_irect = { x, y, x + image_resource->width(), @@ -365,11 +411,18 @@ bool Graphics2D::ReadImageData(PP_Resource image, SkIntToScalar(image_resource->width()), SkIntToScalar(image_resource->height()) }; - // We want to replace the contents of the bitmap rather than blend. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); - dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), - &src_irect, dest_rect, &paint); + if (image_resource->format() != image_data_->format()) { + // Convert the image data if the format does not match. + ConvertImageData(image_data_, src_irect, image_resource.get(), dest_rect); + } else { + skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); + + // We want to replace the contents of the bitmap rather than blend. + SkPaint paint; + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), + &src_irect, dest_rect, &paint); + } return true; } @@ -505,14 +558,19 @@ void Graphics2D::ExecutePaintImageData(ImageData* image, SkIntToScalar(invalidated_rect->right()), SkIntToScalar(invalidated_rect->bottom()) }; - // We're guaranteed to have a mapped canvas since we mapped it in Init(). - skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); + if (image->format() != image_data_->format()) { + // Convert the image data if the format does not match. + ConvertImageData(image, src_irect, image_data_, dest_rect); + } else { + // We're guaranteed to have a mapped canvas since we mapped it in Init(). + skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); - // We want to replace the contents of the bitmap rather than blend. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); - backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), - &src_irect, dest_rect, &paint); + // We want to replace the contents of the bitmap rather than blend. + SkPaint paint; + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), + &src_irect, dest_rect, &paint); + } } void Graphics2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, @@ -524,7 +582,19 @@ void Graphics2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, void Graphics2D::ExecuteReplaceContents(ImageData* image, gfx::Rect* invalidated_rect) { - image_data_->Swap(image); + if (image->format() != image_data_->format()) { + DCHECK(image->width() == image_data_->width() && + image->height() == image_data_->height()); + // Convert the image data if the format does not match. + SkIRect src_irect = { 0, 0, image->width(), image->height() }; + SkRect dest_rect = { SkIntToScalar(0), + SkIntToScalar(0), + SkIntToScalar(image_data_->width()), + SkIntToScalar(image_data_->height()) }; + ConvertImageData(image, src_irect, image_data_, dest_rect); + } else { + image_data_->Swap(image); + } *invalidated_rect = gfx::Rect(0, 0, image_data_->width(), image_data_->height()); } |