Commit 4297bea8 authored by backer@chromium.org's avatar backer@chromium.org

Enable GL_CHROMIUM_post_sub_buffer for osmesa

Small changes to WGC3DInProcessImpl to pass the extension up to WebKit.

BUG=none
TEST=with https://bugs.webkit.org/show_bug.cgi?id=67341 and --use-gl=osmesa


Review URL: http://codereview.chromium.org/8772021

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112738 0039d316-1c4b-4281-b951-d872f2087c98
parent f8530b79
......@@ -584,8 +584,28 @@ XID CreatePictureFromSkiaPixmap(Display* display, XID pixmap) {
return picture;
}
void PutARGBImage(Display* display, void* visual, int depth, XID pixmap,
void* pixmap_gc, const uint8* data, int width, int height) {
void PutARGBImage(Display* display,
void* visual, int depth,
XID pixmap, void* pixmap_gc,
const uint8* data,
int width, int height) {
PutARGBImage(display,
visual, depth,
pixmap, pixmap_gc,
data, width, height,
0, 0, // src_x, src_y
0, 0, // dst_x, dst_y
width, height);
}
void PutARGBImage(Display* display,
void* visual, int depth,
XID pixmap, void* pixmap_gc,
const uint8* data,
int data_width, int data_height,
int src_x, int src_y,
int dst_x, int dst_y,
int copy_width, int copy_height) {
// TODO(scherkus): potential performance impact... consider passing in as a
// parameter.
int pixmap_bpp = BitsPerPixelForPixmapDepth(display, depth);
......@@ -593,15 +613,15 @@ void PutARGBImage(Display* display, void* visual, int depth, XID pixmap,
XImage image;
memset(&image, 0, sizeof(image));
image.width = width;
image.height = height;
image.width = data_width;
image.height = data_height;
image.format = ZPixmap;
image.byte_order = LSBFirst;
image.bitmap_unit = 8;
image.bitmap_bit_order = LSBFirst;
image.depth = depth;
image.bits_per_pixel = pixmap_bpp;
image.bytes_per_line = width * pixmap_bpp / 8;
image.bytes_per_line = data_width * pixmap_bpp / 8;
if (pixmap_bpp == 32) {
image.red_mask = 0xff0000;
......@@ -616,8 +636,8 @@ void PutARGBImage(Display* display, void* visual, int depth, XID pixmap,
image.blue_mask == vis->blue_mask) {
image.data = const_cast<char*>(reinterpret_cast<const char*>(data));
XPutImage(display, pixmap, static_cast<GC>(pixmap_gc), &image,
0, 0 /* source x, y */, 0, 0 /* dest x, y */,
width, height);
src_x, src_y, dst_x, dst_y,
copy_width, copy_height);
} else {
// Otherwise, we need to shuffle the colors around. Assume red and blue
// need to be swapped.
......@@ -625,13 +645,14 @@ void PutARGBImage(Display* display, void* visual, int depth, XID pixmap,
// It's possible to use some fancy SSE tricks here, but since this is the
// slow path anyway, we do it slowly.
uint8_t* bitmap32 = static_cast<uint8_t*>(malloc(4 * width * height));
uint8_t* bitmap32 =
static_cast<uint8_t*>(malloc(4 * data_width * data_height));
if (!bitmap32)
return;
uint8_t* const orig_bitmap32 = bitmap32;
const uint32_t* bitmap_in = reinterpret_cast<const uint32_t*>(data);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
for (int y = 0; y < data_height; ++y) {
for (int x = 0; x < data_width; ++x) {
const uint32_t pixel = *(bitmap_in++);
bitmap32[0] = (pixel >> 16) & 0xff; // Red
bitmap32[1] = (pixel >> 8) & 0xff; // Green
......@@ -642,21 +663,22 @@ void PutARGBImage(Display* display, void* visual, int depth, XID pixmap,
}
image.data = reinterpret_cast<char*>(orig_bitmap32);
XPutImage(display, pixmap, static_cast<GC>(pixmap_gc), &image,
0, 0 /* source x, y */, 0, 0 /* dest x, y */,
width, height);
src_x, src_y, dst_x, dst_y,
copy_width, copy_height);
free(orig_bitmap32);
}
} else if (pixmap_bpp == 16) {
// Some folks have VNC setups which still use 16-bit visuals and VNC
// doesn't include Xrender.
uint16_t* bitmap16 = static_cast<uint16_t*>(malloc(2 * width * height));
uint16_t* bitmap16 =
static_cast<uint16_t*>(malloc(2 * data_width * data_height));
if (!bitmap16)
return;
uint16_t* const orig_bitmap16 = bitmap16;
const uint32_t* bitmap_in = reinterpret_cast<const uint32_t*>(data);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
for (int y = 0; y < data_height; ++y) {
for (int x = 0; x < data_width; ++x) {
const uint32_t pixel = *(bitmap_in++);
uint16_t out_pixel = ((pixel >> 8) & 0xf800) |
((pixel >> 5) & 0x07e0) |
......@@ -671,8 +693,8 @@ void PutARGBImage(Display* display, void* visual, int depth, XID pixmap,
image.blue_mask = 0x001f;
XPutImage(display, pixmap, static_cast<GC>(pixmap_gc), &image,
0, 0 /* source x, y */, 0, 0 /* dest x, y */,
width, height);
src_x, src_y, dst_x, dst_y,
copy_width, copy_height);
free(orig_bitmap16);
} else {
LOG(FATAL) << "Sorry, we don't support your visual depth without "
......
......@@ -178,10 +178,25 @@ UI_EXPORT XID CreatePictureFromSkiaPixmap(Display* display, XID pixmap);
// server side visual depth as needed. Destination is assumed to be the same
// dimensions as |data| or larger. |data| is also assumed to be in row order
// with each line being exactly |width| * 4 bytes long.
UI_EXPORT void PutARGBImage(Display* display, void* visual, int depth,
XID pixmap, void* pixmap_gc, const uint8* data,
UI_EXPORT void PutARGBImage(Display* display,
void* visual, int depth,
XID pixmap, void* pixmap_gc,
const uint8* data,
int width, int height);
// Same as above only more general:
// - |data_width| and |data_height| refer to the data image
// - |src_x|, |src_y|, |copy_width| and |copy_height| define source region
// - |dst_x|, |dst_y|, |copy_width| and |copy_height| define destination region
UI_EXPORT void PutARGBImage(Display* display,
void* visual, int depth,
XID pixmap, void* pixmap_gc,
const uint8* data,
int data_width, int data_height,
int src_x, int src_y,
int dst_x, int dst_y,
int copy_width, int copy_height);
void FreePicture(Display* display, XID picture);
void FreePixmap(Display* display, XID pixmap);
......
......@@ -42,6 +42,8 @@ class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
virtual void Destroy();
virtual bool IsOffscreen();
virtual bool SwapBuffers();
virtual std::string GetExtensions();
virtual bool PostSubBuffer(int x, int y, int width, int height);
private:
bool UpdateSize();
......@@ -194,6 +196,59 @@ bool NativeViewGLSurfaceOSMesa::SwapBuffers() {
return true;
}
std::string NativeViewGLSurfaceOSMesa::GetExtensions() {
std::string extensions = gfx::GLSurfaceOSMesa::GetExtensions();
extensions += extensions.empty() ? "" : " ";
extensions += "GL_CHROMIUM_post_sub_buffer";
return extensions;
}
bool NativeViewGLSurfaceOSMesa::PostSubBuffer(
int x, int y, int width, int height) {
// Update the size before blitting so that the blit size is exactly the same
// as the window.
if (!UpdateSize()) {
LOG(ERROR) << "Failed to update size of GLContextOSMesa.";
return false;
}
gfx::Size size = GetSize();
// Move (0,0) from lower-left to upper-left
y = size.height() - y - height;
XWindowAttributes attributes;
if (!XGetWindowAttributes(g_osmesa_display, window_, &attributes)) {
LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << ".";
return false;
}
// Copy the frame into the pixmap.
ui::PutARGBImage(g_osmesa_display,
attributes.visual,
attributes.depth,
pixmap_,
pixmap_graphics_context_,
static_cast<const uint8*>(GetHandle()),
size.width(),
size.height(),
x, y,
x, y,
width,
height);
// Copy the pixmap to the window.
XCopyArea(g_osmesa_display,
pixmap_,
window_,
window_graphics_context_,
x, y,
width, height,
x, y);
return true;
}
bool NativeViewGLSurfaceOSMesa::UpdateSize() {
// Get the window size.
XWindowAttributes attributes;
......
......@@ -30,6 +30,8 @@ class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
virtual void Destroy();
virtual bool IsOffscreen();
virtual bool SwapBuffers();
virtual std::string GetExtensions();
virtual bool PostSubBuffer(int x, int y, int width, int height);
private:
void UpdateSize();
......@@ -134,6 +136,54 @@ bool NativeViewGLSurfaceOSMesa::SwapBuffers() {
return true;
}
std::string NativeViewGLSurfaceOSMesa::GetExtensions() {
std::string extensions = gfx::GLSurfaceOSMesa::GetExtensions();
extensions += extensions.empty() ? "" : " ";
extensions += "GL_CHROMIUM_post_sub_buffer";
return extensions;
}
bool NativeViewGLSurfaceOSMesa::PostSubBuffer(
int x, int y, int width, int height) {
DCHECK(device_context_);
// Update the size before blitting so that the blit size is exactly the same
// as the window.
UpdateSize();
gfx::Size size = GetSize();
// Note: negating the height below causes GDI to treat the bitmap data as row
// 0 being at the top.
BITMAPV4HEADER info = { sizeof(BITMAPV4HEADER) };
info.bV4Width = size.width();
info.bV4Height = -size.height();
info.bV4Planes = 1;
info.bV4BitCount = 32;
info.bV4V4Compression = BI_BITFIELDS;
info.bV4RedMask = 0x000000FF;
info.bV4GreenMask = 0x0000FF00;
info.bV4BlueMask = 0x00FF0000;
info.bV4AlphaMask = 0xFF000000;
// Copy the back buffer to the window's device context. Do not check whether
// StretchDIBits succeeds or not. It will fail if the window has been
// destroyed but it is preferable to allow rendering to silently fail if the
// window is destroyed. This is because the primary application of this
// class of GLContext is for testing and we do not want every GL related ui /
// browser test to become flaky if there is a race condition between GL
// context destruction and window destruction.
StretchDIBits(device_context_,
x, size.height() - y - height, width, height,
x, y, width, height,
GetHandle(),
reinterpret_cast<BITMAPINFO*>(&info),
DIB_RGB_COLORS,
SRCCOPY);
return true;
}
void NativeViewGLSurfaceOSMesa::UpdateSize() {
// Change back buffer size to that of window. If window handle is invalid, do
// not change the back buffer size.
......
......@@ -1254,8 +1254,9 @@ WebString WebGraphicsContext3DInProcessImpl::getShaderSource(WebGLId shader) {
WebString WebGraphicsContext3DInProcessImpl::getString(WGC3Denum name) {
makeContextCurrent();
std::string result(reinterpret_cast<const char*>(glGetString(name)));
std::string result;
if (name == GL_EXTENSIONS) {
result = gl_context_->GetExtensions();
if (!is_gles2_) {
std::vector<std::string> split;
base::SplitString(result, ' ', &split);
......@@ -1265,6 +1266,8 @@ WebString WebGraphicsContext3DInProcessImpl::getString(WGC3Denum name) {
result += " GL_EXT_texture_format_BGRA8888 GL_EXT_read_format_bgra";
}
}
} else {
result = reinterpret_cast<const char*>(glGetString(name));
}
return WebString::fromUTF8(result.c_str());
}
......
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