mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-27 02:43:07 +00:00
218 lines
7.6 KiB
Diff
218 lines
7.6 KiB
Diff
diff --git a/gfx/gl/GLContextSkia.cpp b/gfx/gl/GLContextSkia.cpp
|
|
--- a/gfx/gl/GLContextSkia.cpp
|
|
+++ b/gfx/gl/GLContextSkia.cpp
|
|
@@ -303,39 +303,47 @@ const GLubyte* glGetString_mozilla(GrGLe
|
|
if (name == LOCAL_GL_VERSION) {
|
|
if (sGLContext.get()->IsGLES2()) {
|
|
return reinterpret_cast<const GLubyte*>("OpenGL ES 2.0");
|
|
} else {
|
|
return reinterpret_cast<const GLubyte*>("2.0");
|
|
}
|
|
} else if (name == LOCAL_GL_EXTENSIONS) {
|
|
// Only expose the bare minimum extensions we want to support to ensure a functional Ganesh
|
|
// as GLContext only exposes certain extensions
|
|
static bool extensionsStringBuilt = false;
|
|
- static char extensionsString[120];
|
|
+ static char extensionsString[256];
|
|
|
|
if (!extensionsStringBuilt) {
|
|
if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_texture_format_BGRA8888)) {
|
|
strcpy(extensionsString, "GL_EXT_texture_format_BGRA8888 ");
|
|
}
|
|
|
|
if (sGLContext.get()->IsExtensionSupported(GLContext::OES_packed_depth_stencil)) {
|
|
strcat(extensionsString, "GL_OES_packed_depth_stencil ");
|
|
}
|
|
|
|
if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_packed_depth_stencil)) {
|
|
strcat(extensionsString, "GL_EXT_packed_depth_stencil ");
|
|
}
|
|
|
|
if (sGLContext.get()->IsExtensionSupported(GLContext::OES_rgb8_rgba8)) {
|
|
strcat(extensionsString, "GL_OES_rgb8_rgba8 ");
|
|
}
|
|
|
|
+ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_bgra)) {
|
|
+ strcat(extensionsString, "GL_EXT_bgra ");
|
|
+ }
|
|
+
|
|
+ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_read_format_bgra)) {
|
|
+ strcat(extensionsString, "GL_EXT_read_format_bgra ");
|
|
+ }
|
|
+
|
|
extensionsStringBuilt = true;
|
|
}
|
|
|
|
return reinterpret_cast<const GLubyte*>(extensionsString);
|
|
|
|
} else if (name == LOCAL_GL_SHADING_LANGUAGE_VERSION) {
|
|
if (sGLContext.get()->IsGLES2()) {
|
|
return reinterpret_cast<const GLubyte*>("OpenGL ES GLSL ES 1.0");
|
|
} else {
|
|
return reinterpret_cast<const GLubyte*>("1.10");
|
|
diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.cpp b/gfx/skia/src/gpu/gl/GrGpuGL.cpp
|
|
--- a/gfx/skia/src/gpu/gl/GrGpuGL.cpp
|
|
+++ b/gfx/skia/src/gpu/gl/GrGpuGL.cpp
|
|
@@ -1,18 +1,18 @@
|
|
/*
|
|
* Copyright 2011 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
-
|
|
+#include <algorithm>
|
|
#include "GrGpuGL.h"
|
|
#include "GrGLStencilBuffer.h"
|
|
#include "GrGLPath.h"
|
|
#include "GrGLShaderBuilder.h"
|
|
#include "GrTemplates.h"
|
|
#include "GrTypes.h"
|
|
#include "SkTemplates.h"
|
|
|
|
static const GrGLuint GR_MAX_GLUINT = ~0U;
|
|
static const GrGLint GR_INVAL_GLINT = ~0;
|
|
@@ -1381,29 +1381,67 @@ bool GrGpuGL::readPixelsWillPayForYFlip(
|
|
// Note the rowBytes might be tight to the passed in data, but if data
|
|
// gets clipped in x to the target the rowBytes will no longer be tight.
|
|
if (left >= 0 && (left + width) < renderTarget->width()) {
|
|
return 0 == rowBytes ||
|
|
GrBytesPerPixel(config) * width == rowBytes;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+static void swizzleRow(void* buffer, int byteLen) {
|
|
+ uint8_t* src = (uint8_t*)buffer;
|
|
+ uint8_t* end = src + byteLen;
|
|
+
|
|
+ GrAssert((end - src) % 4 == 0);
|
|
+
|
|
+ for (; src != end; src += 4) {
|
|
+ std::swap(src[0], src[2]);
|
|
+ }
|
|
+}
|
|
+
|
|
+bool GrGpuGL::canReadBGRA() const
|
|
+{
|
|
+ if (kDesktop_GrGLBinding == this->glBinding() ||
|
|
+ this->hasExtension("GL_EXT_bgra"))
|
|
+ return true;
|
|
+
|
|
+ if (this->hasExtension("GL_EXT_read_format_bgra")) {
|
|
+ GrGLint readFormat = 0;
|
|
+ GrGLint readType = 0;
|
|
+
|
|
+ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat));
|
|
+ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType));
|
|
+
|
|
+ return readFormat == GR_GL_BGRA && readType == GR_GL_UNSIGNED_BYTE;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
bool GrGpuGL::onReadPixels(GrRenderTarget* target,
|
|
int left, int top,
|
|
int width, int height,
|
|
GrPixelConfig config,
|
|
void* buffer,
|
|
size_t rowBytes) {
|
|
GrGLenum format;
|
|
GrGLenum type;
|
|
bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin();
|
|
+ bool needSwizzle = false;
|
|
+
|
|
+ if (kBGRA_8888_GrPixelConfig == config && !this->canReadBGRA()) {
|
|
+ // Read RGBA and swizzle after
|
|
+ config = kRGBA_8888_GrPixelConfig;
|
|
+ needSwizzle = true;
|
|
+ }
|
|
+
|
|
if (!this->configToGLFormats(config, false, NULL, &format, &type)) {
|
|
return false;
|
|
}
|
|
size_t bpp = GrBytesPerPixel(config);
|
|
if (!adjust_pixel_ops_params(target->width(), target->height(), bpp,
|
|
&left, &top, &width, &height,
|
|
const_cast<const void**>(&buffer),
|
|
&rowBytes)) {
|
|
return false;
|
|
}
|
|
@@ -1478,35 +1516,46 @@ bool GrGpuGL::onReadPixels(GrRenderTarge
|
|
scratch.reset(tightRowBytes);
|
|
void* tmpRow = scratch.get();
|
|
// flip y in-place by rows
|
|
const int halfY = height >> 1;
|
|
char* top = reinterpret_cast<char*>(buffer);
|
|
char* bottom = top + (height - 1) * rowBytes;
|
|
for (int y = 0; y < halfY; y++) {
|
|
memcpy(tmpRow, top, tightRowBytes);
|
|
memcpy(top, bottom, tightRowBytes);
|
|
memcpy(bottom, tmpRow, tightRowBytes);
|
|
+
|
|
+ if (needSwizzle) {
|
|
+ swizzleRow(top, tightRowBytes);
|
|
+ swizzleRow(bottom, tightRowBytes);
|
|
+ }
|
|
+
|
|
top += rowBytes;
|
|
bottom -= rowBytes;
|
|
}
|
|
}
|
|
} else {
|
|
- GrAssert(readDst != buffer); GrAssert(rowBytes != tightRowBytes);
|
|
+ GrAssert(readDst != buffer);
|
|
+ GrAssert(rowBytes != tightRowBytes);
|
|
// copy from readDst to buffer while flipping y
|
|
// const int halfY = height >> 1;
|
|
const char* src = reinterpret_cast<const char*>(readDst);
|
|
char* dst = reinterpret_cast<char*>(buffer);
|
|
if (flipY) {
|
|
dst += (height-1) * rowBytes;
|
|
}
|
|
for (int y = 0; y < height; y++) {
|
|
memcpy(dst, src, tightRowBytes);
|
|
+ if (needSwizzle) {
|
|
+ swizzleRow(dst, tightRowBytes);
|
|
+ }
|
|
+
|
|
src += readDstRowBytes;
|
|
if (!flipY) {
|
|
dst += rowBytes;
|
|
} else {
|
|
dst -= rowBytes;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.h b/gfx/skia/src/gpu/gl/GrGpuGL.h
|
|
--- a/gfx/skia/src/gpu/gl/GrGpuGL.h
|
|
+++ b/gfx/skia/src/gpu/gl/GrGpuGL.h
|
|
@@ -243,20 +243,22 @@ private:
|
|
GrPixelConfig dataConfig,
|
|
const void* data,
|
|
size_t rowBytes);
|
|
|
|
bool createRenderTargetObjects(int width, int height,
|
|
GrGLuint texID,
|
|
GrGLRenderTarget::Desc* desc);
|
|
|
|
void fillInConfigRenderableTable();
|
|
|
|
+ bool canReadBGRA() const;
|
|
+
|
|
GrGLContext fGLContext;
|
|
|
|
// GL program-related state
|
|
ProgramCache* fProgramCache;
|
|
SkAutoTUnref<GrGLProgram> fCurrentProgram;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///@name Caching of GL State
|
|
///@{
|
|
int fHWActiveTextureUnitIdx;
|