2010-08-12 Stephen White <senorblanco@chromium.org>

        Reviewed by David Levin.

        [CHROMIUM] Use the BGRA format for canvas 2D accel upload and readbacks.
        https://bugs.webkit.org/show_bug.cgi?id=43804

        Use the BGRA format from GraphicsContext3D, if supported.  Also keep a
        texture around for uploads, rather than re-creating it each time.

        Covered by many layout tests (once we're running them).

        * platform/graphics/chromium/GLES2Texture.cpp:
        (WebCore::convertFormat):
        Move convertFormat() ahead of texture creation, so we can check for
        BGRA support.
        (WebCore::GLES2Texture::create):
        Use convertFormat() to determine the correct format and types to use;
        use the returned format also for internalFormat, since GLES2 insists
        they match.
        * platform/graphics/skia/PlatformContextSkia.cpp:
        (WebCore::PlatformContextSkia::setGraphicsContext3D):
        Clear the upload texture when a new context is set.
        (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
        Use m_uploadTexture instead of creating a new one each time.
        (WebCore::PlatformContextSkia::readbackHardwareToSoftware):
        When the context supports it, use the BGRA format for readbacks
        instead of swizzling.
        * platform/graphics/skia/PlatformContextSkia.h:
        Add m_uploadTexture for consecutive uploads.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65323 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 202ce576
2010-08-12 Stephen White <senorblanco@chromium.org>
Reviewed by David Levin.
[CHROMIUM] Use the BGRA format for canvas 2D accel upload and readbacks.
https://bugs.webkit.org/show_bug.cgi?id=43804
Use the BGRA format from GraphicsContext3D, if supported. Also keep a
texture around for uploads, rather than re-creating it each time.
Covered by many layout tests (once we're running them).
* platform/graphics/chromium/GLES2Texture.cpp:
(WebCore::convertFormat):
Move convertFormat() ahead of texture creation, so we can check for
BGRA support.
(WebCore::GLES2Texture::create):
Use convertFormat() to determine the correct format and types to use;
use the returned format also for internalFormat, since GLES2 insists
they match.
* platform/graphics/skia/PlatformContextSkia.cpp:
(WebCore::PlatformContextSkia::setGraphicsContext3D):
Clear the upload texture when a new context is set.
(WebCore::PlatformContextSkia::uploadSoftwareToHardware):
Use m_uploadTexture instead of creating a new one each time.
(WebCore::PlatformContextSkia::readbackHardwareToSoftware):
When the context supports it, use the BGRA format for readbacks
instead of swizzling.
* platform/graphics/skia/PlatformContextSkia.h:
Add m_uploadTexture for consecutive uploads.
2010-08-13 Simon Hausmann <simon.hausmann@nokia.com>
Reviewed by Ariya Hidayat.
......@@ -54,6 +54,30 @@ GLES2Texture::~GLES2Texture()
m_context->deleteTexture(m_textureId);
}
static void convertFormat(GraphicsContext3D* context, GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle)
{
*swizzle = false;
switch (format) {
case GLES2Texture::RGBA8:
*glFormat = GraphicsContext3D::RGBA;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
break;
case GLES2Texture::BGRA8:
if (context->supportsBGRA()) {
*glFormat = GraphicsContext3D::BGRA_EXT;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
} else {
*glFormat = GraphicsContext3D::RGBA;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
*swizzle = true;
}
break;
default:
ASSERT_NOT_REACHED();
break;
}
}
PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format format, int width, int height)
{
int max;
......@@ -67,38 +91,20 @@ PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format
if (!textureId)
return 0;
unsigned int glFormat, glType;
bool swizzle;
convertFormat(context, format, &glFormat, &glType, &swizzle);
context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, width, height, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, glFormat, width, height, 0, glFormat, glType, 0);
return adoptRef(new GLES2Texture(context, textureId, format, width, height));
}
static void convertFormat(GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle)
{
*swizzle = false;
switch (format) {
case GLES2Texture::RGBA8:
*glFormat = GraphicsContext3D::RGBA;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
break;
case GLES2Texture::BGRA8:
// FIXME: Once we have support for extensions, we should check for EXT_texture_format_BGRA8888,
// and use that if present.
*glFormat = GraphicsContext3D::RGBA;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
*swizzle = true;
break;
default:
ASSERT(!"bad format");
break;
}
}
void GLES2Texture::load(void* pixels)
{
unsigned int glFormat, glType;
bool swizzle;
convertFormat(m_format, &glFormat, &glType, &swizzle);
convertFormat(m_context, m_format, &glFormat, &glType, &swizzle);
m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId);
if (swizzle) {
ASSERT(glFormat == GraphicsContext3D::RGBA && glType == GraphicsContext3D::UNSIGNED_BYTE);
......
......@@ -706,6 +706,7 @@ void PlatformContextSkia::setGraphicsContext3D(GraphicsContext3D* context, const
{
m_useGPU = true;
m_gpuCanvas = new GLES2Canvas(context, size);
m_uploadTexture.clear();
#if USE(ACCELERATED_COMPOSITING)
CanvasLayerChromium* layer = static_cast<CanvasLayerChromium*>(context->platformLayer());
layer->setPrepareTextureCallback(PrepareTextureCallbackImpl::create(this));
......@@ -791,13 +792,13 @@ void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const
{
const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false);
SkAutoLockPixels lock(bitmap);
// FIXME: Keep a texture around for this rather than constantly creating/destroying one.
GraphicsContext3D* context = m_gpuCanvas->context();
RefPtr<GLES2Texture> texture = GLES2Texture::create(context, GLES2Texture::BGRA8, bitmap.width(), bitmap.height());
texture->load(bitmap.getPixels());
if (!m_uploadTexture || m_uploadTexture->width() < bitmap.width() || m_uploadTexture->height() < bitmap.height())
m_uploadTexture = GLES2Texture::create(context, GLES2Texture::BGRA8, bitmap.width(), bitmap.height());
m_uploadTexture->load(bitmap.getPixels());
IntRect rect(0, 0, bitmap.width(), bitmap.height());
AffineTransform identity;
gpuCanvas()->drawTexturedRect(texture.get(), rect, rect, identity, 1.0, DeviceColorSpace, op);
gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), rect, rect, identity, 1.0, DeviceColorSpace, op);
}
void PlatformContextSkia::readbackHardwareToSoftware() const
......@@ -810,11 +811,15 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
// Flips the image vertically.
for (int y = 0; y < height; ++y) {
uint32_t* pixels = bitmap.getAddr32(0, y);
context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels);
for (int i = 0; i < width; ++i) {
uint32_t pixel = pixels[i];
// Swizzles from RGBA -> BGRA.
pixels[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
if (context->supportsBGRA())
context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::BGRA_EXT, GraphicsContext3D::UNSIGNED_BYTE, pixels);
else {
context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels);
for (int i = 0; i < width; ++i) {
uint32_t pixel = pixels[i];
// Swizzles from RGBA -> BGRA.
pixels[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
}
}
}
}
......
......@@ -48,6 +48,7 @@ namespace WebCore {
#if USE(GLES2_RENDERING)
enum CompositeOperator;
class GLES2Canvas;
class GLES2Texture;
class GraphicsContext3D;
#endif
......@@ -240,6 +241,7 @@ private:
bool m_useGPU;
OwnPtr<GLES2Canvas> m_gpuCanvas;
mutable enum { None, Software, Mixed, Hardware } m_backingStoreState;
mutable RefPtr<GLES2Texture> m_uploadTexture;
#endif
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment