Bug 1457546 - Use glMapBufferRange instead of glMapBuffer to capture screenshots r=jgilbert

It was pointed out in a review by jgilbert that glMapBuffer only supports
writing to the mapped range on an OpenGL ES profile and using it to read is
undefined behaviour. We now use glMapBufferRange when available, which does
support reading on both OpenGL and OpenGL ES profiles, and allows capturing
screenshots on Android. When it is not available, we fall back to glMapBuffer
(e.g., for macOS).

Differential Revision: https://phabricator.services.mozilla.com/D12341

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Barret Rennie 2018-11-20 18:32:10 +00:00
Родитель 4575169eee
Коммит b09ba3de12
4 изменённых файлов: 17 добавлений и 3 удалений

Просмотреть файл

@ -139,6 +139,7 @@ static const char* const sExtensionNames[] = {
"GL_EXT_framebuffer_object",
"GL_EXT_framebuffer_sRGB",
"GL_EXT_gpu_shader4",
"GL_EXT_map_buffer_range",
"GL_EXT_multisampled_render_to_texture",
"GL_EXT_occlusion_query_boolean",
"GL_EXT_packed_depth_stencil",

Просмотреть файл

@ -440,6 +440,7 @@ public:
EXT_framebuffer_object,
EXT_framebuffer_sRGB,
EXT_gpu_shader4,
EXT_map_buffer_range,
EXT_multisampled_render_to_texture,
EXT_occlusion_query_boolean,
EXT_packed_depth_stencil,

Просмотреть файл

@ -372,6 +372,7 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLESVersion::ES3,
GLContext::ARB_map_buffer_range,
{
GLContext::EXT_map_buffer_range,
GLContext::Extensions_End
}
},

Просмотреть файл

@ -126,8 +126,19 @@ AsyncReadbackBufferOGL::MapAndCopyInto(DataSourceSurface* aSurface,
ScopedPackState scopedPackState(mGL);
Bind();
uint8_t* srcData = static_cast<uint8_t*>(
mGL->fMapBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, LOCAL_GL_READ_ONLY));
const uint8_t *srcData = nullptr;
if (mGL->IsSupported(GLFeature::map_buffer_range)) {
srcData = static_cast<uint8_t*>(
mGL->fMapBufferRange(
LOCAL_GL_PIXEL_PACK_BUFFER,
0,
aReadSize.height * aReadSize.width * 4,
LOCAL_GL_MAP_READ_BIT));
} else {
srcData = static_cast<uint8_t*>(
mGL->fMapBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, LOCAL_GL_READ_ONLY));
}
if (!srcData) {
return false;
@ -141,7 +152,7 @@ AsyncReadbackBufferOGL::MapAndCopyInto(DataSourceSurface* aSurface,
for (int32_t destRow = 0; destRow < aReadSize.height; destRow++) {
// Turn srcData upside down during the copy.
int32_t srcRow = aReadSize.height - 1 - destRow;
uint8_t* src = &srcData[srcRow * srcStride];
const uint8_t* src = &srcData[srcRow * srcStride];
uint8_t* dest = &destData[destRow * destStride];
SwizzleData(src, srcStride, SurfaceFormat::R8G8B8A8,
dest, destStride, destFormat, IntSize(aReadSize.width, 1));