Commit 6809a4d6 authored by danakj's avatar danakj Committed by Commit Bot

Use scanout overlays for pepper2d when possible.

If GL image textures are supported, and we can find the image texture
target for the desired format, then use TexStorage2DImageCHROMIUM to
allocate the texture so that it may be used for scanout.

R=piman@chromium.org

Bug: 786140
Change-Id: I36875f82796614f4d5c7290f27bd0bacfce510fb
Reviewed-on: https://chromium-review.googlesource.com/779883Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Commit-Queue: danakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#518269}
parent 22ef5abe
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "content/renderer/pepper/plugin_instance_throttler_impl.h" #include "content/renderer/pepper/plugin_instance_throttler_impl.h"
#include "content/renderer/pepper/ppb_image_data_impl.h" #include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/capabilities.h"
#include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_bool.h"
...@@ -199,7 +200,7 @@ PepperGraphics2DHost::~PepperGraphics2DHost() { ...@@ -199,7 +200,7 @@ PepperGraphics2DHost::~PepperGraphics2DHost() {
// compositor, since those will be deleted by ReleaseTextureCallback() when it // compositor, since those will be deleted by ReleaseTextureCallback() when it
// runs. // runs.
while (main_thread_context_ && !recycled_texture_copies_.empty()) { while (main_thread_context_ && !recycled_texture_copies_.empty()) {
uint32_t texture_id = recycled_texture_copies_.back().first; uint32_t texture_id = recycled_texture_copies_.back().id;
main_thread_context_->ContextGL()->DeleteTextures(1, &texture_id); main_thread_context_->ContextGL()->DeleteTextures(1, &texture_id);
recycled_texture_copies_.pop_back(); recycled_texture_copies_.pop_back();
} }
...@@ -226,6 +227,22 @@ bool PepperGraphics2DHost::Init( ...@@ -226,6 +227,22 @@ bool PepperGraphics2DHost::Init(
} }
is_always_opaque_ = is_always_opaque; is_always_opaque_ = is_always_opaque;
scale_ = 1.0f; scale_ = 1.0f;
// Gets the texture target for RGBA and BGRA textures if we can make
// image-backed textures for direct scanout (for use in overlays).
RenderThreadImpl* rti = RenderThreadImpl::current();
if (rti) {
const auto& map = rti->GetBufferToTextureTargetMap();
auto target_it = map.find(viz::BufferToTextureTargetKey(
gfx::BufferUsage::SCANOUT, gfx::BufferFormat::BGRA_8888));
if (target_it != map.end())
scanout_texture_target_bgra_ = target_it->second;
target_it = map.find(viz::BufferToTextureTargetKey(
gfx::BufferUsage::SCANOUT, gfx::BufferFormat::RGBA_8888));
if (target_it != map.end())
scanout_texture_target_rgba_ = target_it->second;
}
return true; return true;
} }
...@@ -581,7 +598,7 @@ void PepperGraphics2DHost::ReleaseTextureCallback( ...@@ -581,7 +598,7 @@ void PepperGraphics2DHost::ReleaseTextureCallback(
// the busy textures list to the recycled list. // the busy textures list to the recycled list.
auto it = host->texture_copies_.begin(); auto it = host->texture_copies_.begin();
for (; it != host->texture_copies_.end(); ++it) { for (; it != host->texture_copies_.end(); ++it) {
if (it->first == id) { if (it->id == id) {
host->recycled_texture_copies_.push_back(*it); host->recycled_texture_copies_.push_back(*it);
host->texture_copies_.erase(it); host->texture_copies_.erase(it);
break; break;
...@@ -593,9 +610,7 @@ void PepperGraphics2DHost::ReleaseTextureCallback( ...@@ -593,9 +610,7 @@ void PepperGraphics2DHost::ReleaseTextureCallback(
// The otherwise, the texture can not be reused so remove it from the busy // The otherwise, the texture can not be reused so remove it from the busy
// texture list and delete it. // texture list and delete it.
if (host) { if (host) {
auto matches_id = [id](const std::pair<uint32_t, gpu::Mailbox>& element) { auto matches_id = [id](const TextureInfo& info) { return info.id == id; };
return element.first == id;
};
base::EraseIf(host->texture_copies_, matches_id); base::EraseIf(host->texture_copies_, matches_id);
} }
context->ContextGL()->DeleteTextures(1, &id); context->ContextGL()->DeleteTextures(1, &id);
...@@ -640,36 +655,77 @@ bool PepperGraphics2DHost::PrepareTransferableResource( ...@@ -640,36 +655,77 @@ bool PepperGraphics2DHost::PrepareTransferableResource(
// |image_data_| into a texture. // |image_data_| into a texture.
if (main_thread_context_) { if (main_thread_context_) {
auto* gl = main_thread_context_->ContextGL(); auto* gl = main_thread_context_->ContextGL();
uint32_t texture_id;
// The bitmap in |image_data_| uses the skia N32 byte order.
constexpr bool bitmap_is_bgra = kN32_SkColorType == kBGRA_8888_SkColorType;
const bool texture_can_be_bgra =
main_thread_context_->ContextCapabilities().texture_format_bgra8888;
const bool upload_bgra = bitmap_is_bgra && texture_can_be_bgra;
const GLenum format = upload_bgra ? GL_BGRA_EXT : GL_RGBA;
bool overlay_candidate = false;
uint32_t texture_target = GL_TEXTURE_2D;
uint32_t storage_format = 0;
if (main_thread_context_->ContextCapabilities().texture_storage_image) {
if (upload_bgra && scanout_texture_target_bgra_) {
texture_target = scanout_texture_target_bgra_;
storage_format = GL_BGRA8_EXT;
overlay_candidate = true;
} else if (!upload_bgra && scanout_texture_target_rgba_) {
texture_target = scanout_texture_target_rgba_;
storage_format = GL_RGBA8_OES;
overlay_candidate = true;
}
}
const gfx::Size size(image_data_->width(), image_data_->height());
uint32_t texture_id = 0;
gpu::Mailbox gpu_mailbox; gpu::Mailbox gpu_mailbox;
if (!recycled_texture_copies_.empty()) { while (!recycled_texture_copies_.empty()) {
texture_id = recycled_texture_copies_.back().first; if (recycled_texture_copies_.back().size == size) {
gpu_mailbox = recycled_texture_copies_.back().second; texture_id = recycled_texture_copies_.back().id;
gpu_mailbox = recycled_texture_copies_.back().mailbox;
recycled_texture_copies_.pop_back();
gl->BindTexture(texture_target, texture_id);
break;
}
uint32_t id = recycled_texture_copies_.back().id;
main_thread_context_->ContextGL()->DeleteTextures(1, &id);
recycled_texture_copies_.pop_back(); recycled_texture_copies_.pop_back();
gl->BindTexture(GL_TEXTURE_2D, texture_id); }
} else { if (!texture_id) {
gl->GenTextures(1, &texture_id); gl->GenTextures(1, &texture_id);
gl->BindTexture(GL_TEXTURE_2D, texture_id); gl->BindTexture(texture_target, texture_id);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl->GenMailboxCHROMIUM(gpu_mailbox.name); gl->GenMailboxCHROMIUM(gpu_mailbox.name);
gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name); gl->ProduceTextureCHROMIUM(texture_target, gpu_mailbox.name);
if (overlay_candidate) {
gl->TexStorage2DImageCHROMIUM(texture_target, storage_format,
GL_SCANOUT_CHROMIUM, size.width(),
size.height());
} else {
gl->TexImage2D(texture_target, 0, format, size.width(), size.height(),
0, format, GL_UNSIGNED_BYTE, nullptr);
}
} }
texture_copies_.push_back(std::make_pair(texture_id, gpu_mailbox)); TextureInfo info;
info.id = texture_id;
info.mailbox = gpu_mailbox;
info.size = size;
texture_copies_.push_back(std::move(info));
void* src = image_data_->Map(); void* src = image_data_->Map();
// The bitmap in |image_data_| uses the skia N32 byte order.
constexpr bool bitmap_is_bgra = kN32_SkColorType == kBGRA_8888_SkColorType;
bool texture_can_be_bgra =
main_thread_context_->ContextCapabilities().texture_format_bgra8888;
// Convert to RGBA if we can't upload BGRA. This is slow sad times. // Convert to RGBA if we can't upload BGRA. This is slow sad times.
std::unique_ptr<uint32_t[]> swizzled; std::unique_ptr<uint32_t[]> swizzled;
if (bitmap_is_bgra && !texture_can_be_bgra) { if (bitmap_is_bgra != upload_bgra) {
size_t num_pixels = (base::CheckedNumeric<size_t>(image_data_->width()) * size_t num_pixels = (base::CheckedNumeric<size_t>(image_data_->width()) *
image_data_->height()) image_data_->height())
.ValueOrDie(); .ValueOrDie();
...@@ -678,10 +734,8 @@ bool PepperGraphics2DHost::PrepareTransferableResource( ...@@ -678,10 +734,8 @@ bool PepperGraphics2DHost::PrepareTransferableResource(
src = swizzled.get(); src = swizzled.get();
} }
GLenum format = gl->TexSubImage2D(texture_target, 0, 0, 0, size.width(), size.height(),
bitmap_is_bgra && texture_can_be_bgra ? GL_BGRA_EXT : GL_RGBA; format, GL_UNSIGNED_BYTE, src);
gl->TexImage2D(GL_TEXTURE_2D, 0, format, image_data_->width(),
image_data_->height(), 0, format, GL_UNSIGNED_BYTE, src);
image_data_->Unmap(); image_data_->Unmap();
swizzled.reset(); swizzled.reset();
...@@ -690,11 +744,11 @@ bool PepperGraphics2DHost::PrepareTransferableResource( ...@@ -690,11 +744,11 @@ bool PepperGraphics2DHost::PrepareTransferableResource(
gl->OrderingBarrierCHROMIUM(); gl->OrderingBarrierCHROMIUM();
gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
gl->BindTexture(GL_TEXTURE_2D, 0); gl->BindTexture(texture_target, 0);
*transferable_resource = *transferable_resource = viz::TransferableResource::MakeGLOverlay(
viz::TransferableResource::MakeGL(std::move(gpu_mailbox), GL_LINEAR, std::move(gpu_mailbox), GL_LINEAR, texture_target,
GL_TEXTURE_2D, std::move(sync_token)); std::move(sync_token), size, overlay_candidate);
*release_callback = viz::SingleReleaseCallback::Create( *release_callback = viz::SingleReleaseCallback::Create(
base::Bind(&ReleaseTextureCallback, this->AsWeakPtr(), base::Bind(&ReleaseTextureCallback, this->AsWeakPtr(),
main_thread_context_, texture_id)); main_thread_context_, texture_id));
......
...@@ -231,14 +231,21 @@ class CONTENT_EXPORT PepperGraphics2DHost ...@@ -231,14 +231,21 @@ class CONTENT_EXPORT PepperGraphics2DHost
// The shared main thread context provider, used to upload 2d pepper frames // The shared main thread context provider, used to upload 2d pepper frames
// if the compositor is expecting gpu content. // if the compositor is expecting gpu content.
scoped_refptr<viz::ContextProvider> main_thread_context_; scoped_refptr<viz::ContextProvider> main_thread_context_;
struct TextureInfo {
uint32_t id;
gpu::Mailbox mailbox;
gfx::Size size;
};
// The ids of textures holding the copied contents of software frames to // The ids of textures holding the copied contents of software frames to
// give to the compositor via GL. Textures in this list are in use by the // give to the compositor via GL. Textures in this list are in use by the
// compositor and are treated as owned by the compositor until the // compositor and are treated as owned by the compositor until the
// ReleaseTextureCallback() informs otherwise. // ReleaseTextureCallback() informs otherwise.
std::vector<std::pair<uint32_t, gpu::Mailbox>> texture_copies_; std::vector<TextureInfo> texture_copies_;
// Texture ids move from |texture_copies_| to here once they are available for // Texture ids move from |texture_copies_| to here once they are available for
// reuse. // reuse.
std::vector<std::pair<uint32_t, gpu::Mailbox>> recycled_texture_copies_; std::vector<TextureInfo> recycled_texture_copies_;
uint32_t scanout_texture_target_rgba_ = 0;
uint32_t scanout_texture_target_bgra_ = 0;
// This is a bitmap that was recently released by the compositor and may be // This is a bitmap that was recently released by the compositor and may be
// used to transfer bytes to the compositor again. // used to transfer bytes to the compositor again.
......
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