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

Unified Diff: Source/core/platform/graphics/GraphicsContext3D.cpp

Issue 17859003: Allow DrawingBuffer to present to a bitmap. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 6 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
Index: Source/core/platform/graphics/GraphicsContext3D.cpp
diff --git a/Source/core/platform/graphics/GraphicsContext3D.cpp b/Source/core/platform/graphics/GraphicsContext3D.cpp
index 2ff862ed02a5668a21123dbe66b68a5b73d8ec0e..a5deef4c28c874c3b214dc2e70fac0d9ff7f8a8b 100644
--- a/Source/core/platform/graphics/GraphicsContext3D.cpp
+++ b/Source/core/platform/graphics/GraphicsContext3D.cpp
@@ -87,6 +87,7 @@ GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D> we
, m_initializedAvailableExtensions(false)
, m_layerComposited(false)
, m_preserveDrawingBuffer(preserveDrawingBuffer)
+ , m_packAlignment(4)
, m_resourceSafety(ResourceSafetyUnknown)
, m_grContext(0)
{
@@ -98,6 +99,7 @@ GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3DProv
, m_initializedAvailableExtensions(false)
, m_layerComposited(false)
, m_preserveDrawingBuffer(preserveDrawingBuffer)
+ , m_packAlignment(4)
, m_resourceSafety(ResourceSafetyUnknown)
, m_grContext(m_provider->grContext())
{
@@ -500,7 +502,14 @@ DELEGATE_TO_WEBCONTEXT_1R(isShader, Platform3DObject, GC3Dboolean)
DELEGATE_TO_WEBCONTEXT_1R(isTexture, Platform3DObject, GC3Dboolean)
DELEGATE_TO_WEBCONTEXT_1(lineWidth, GC3Dfloat)
DELEGATE_TO_WEBCONTEXT_1(linkProgram, Platform3DObject)
-DELEGATE_TO_WEBCONTEXT_2(pixelStorei, GC3Denum, GC3Dint)
+
+void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param)
+{
+ if (pname == PACK_ALIGNMENT)
+ m_packAlignment = param;
+ m_impl->pixelStorei(pname, param);
+}
+
DELEGATE_TO_WEBCONTEXT_2(polygonOffset, GC3Dfloat, GC3Dfloat)
DELEGATE_TO_WEBCONTEXT_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, void*)
@@ -604,17 +613,43 @@ PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData(Drawin
RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
unsigned char* pixels = imageData->data()->data();
- size_t bufferSize = 4 * width * height;
- m_impl->readBackFramebuffer(pixels, bufferSize, framebufferId, width, height);
+ m_impl->bindFramebuffer(FRAMEBUFFER, framebufferId);
+ readBackFramebuffer(pixels, width, height, ReadbackRGBA, AlphaDoNothing);
+ flipVertically(pixels, width, height);
+ return imageData.release();
+}
+
+void GraphicsContext3D::readBackFramebuffer(unsigned char* pixels, int width, int height, ReadbackOrder readbackOrder, AlphaOp op)
+{
+ if (m_packAlignment > 4)
+ m_impl->pixelStorei(PACK_ALIGNMENT, 1);
+ m_impl->readPixels(0, 0, width, height, RGBA, UNSIGNED_BYTE, pixels);
+ if (m_packAlignment > 4)
+ m_impl->pixelStorei(PACK_ALIGNMENT, m_packAlignment);
+
+ size_t bufferSize = 4 * width * height;
+
+ if (readbackOrder == ReadbackSkia) {
#if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT
- // If the implementation swapped the red and blue channels, un-swap them.
- for (size_t i = 0; i < bufferSize; i += 4)
- std::swap(pixels[i], pixels[i + 2]);
+ // Swizzle red and blue channels to match SkBitmap's byte ordering.
+ // TODO(kbr): expose GL_BGRA as extension.
+ for (size_t i = 0; i < bufferSize; i += 4) {
+ std::swap(pixels[i], pixels[i + 2]);
+ }
#endif
+ }
- return imageData.release();
+ if (op == AlphaDoPremultiply) {
+ for (size_t i = 0; i < bufferSize; i += 4) {
+ pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
+ pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
+ pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
+ }
+ } else if (op != AlphaDoNothing) {
+ ASSERT_NOT_REACHED();
+ }
}
DELEGATE_TO_WEBCONTEXT_R(createBuffer, Platform3DObject)
@@ -890,7 +925,6 @@ unsigned GraphicsContext3D::getChannelBitsByFormat(GC3Denum format)
void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int height, bool premultiplyAlpha, ImageBuffer* imageBuffer)
{
unsigned char* pixels = 0;
- size_t bufferSize = 4 * width * height;
const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap();
const SkBitmap* readbackBitmap = 0;
@@ -916,15 +950,9 @@ void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int
SkAutoLockPixels bitmapLock(*readbackBitmap);
pixels = static_cast<unsigned char*>(readbackBitmap->getPixels());
- m_impl->readBackFramebuffer(pixels, 4 * width * height, framebuffer, width, height);
-
- if (premultiplyAlpha) {
- for (size_t i = 0; i < bufferSize; i += 4) {
- pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
- pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
- pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
- }
- }
+ m_impl->bindFramebuffer(FRAMEBUFFER, framebuffer);
+ readBackFramebuffer(pixels, width, height, ReadbackSkia, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing);
+ flipVertically(pixels, width, height);
readbackBitmap->notifyPixelsChanged();
if (m_resizingBitmap.readyToDraw()) {
@@ -1009,4 +1037,19 @@ bool GraphicsContext3D::isExtensionEnabled(const String& name)
return m_enabledExtensions.contains(mappedName);
}
+void GraphicsContext3D::flipVertically(uint8_t* framebuffer, int width, int height)
+{
+ m_scanline.resize(width * 4);
+ uint8* scanline = &m_scanline[0];
+ unsigned rowBytes = width * 4;
+ unsigned count = height / 2;
+ for (unsigned i = 0; i < count; i++) {
+ uint8* rowA = framebuffer + i * rowBytes;
+ uint8* rowB = framebuffer + (height - i - 1) * rowBytes;
+ memcpy(scanline, rowB, rowBytes);
+ memcpy(rowB, rowA, rowBytes);
+ memcpy(rowA, scanline, rowBytes);
+ }
+}
+
} // namespace WebCore
« no previous file with comments | « Source/core/platform/graphics/GraphicsContext3D.h ('k') | Source/core/platform/graphics/chromium/Canvas2DLayerBridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698