| Index: cc/output/gl_renderer.cc
|
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
|
| index 9456c005c2e19dd4f111a81a4984a05e9d31dc65..66d67121695aec6b070388cdd4327d50d4ab9d37 100644
|
| --- a/cc/output/gl_renderer.cc
|
| +++ b/cc/output/gl_renderer.cc
|
| @@ -2796,7 +2796,7 @@ void GLRenderer::DidReceiveTextureInUseResponses(
|
| DCHECK(settings_->release_overlay_resources_after_gpu_query);
|
| for (const gpu::TextureInUseResponse& response : responses) {
|
| if (!response.in_use) {
|
| - swapped_and_acked_overlay_resources_.erase(response.texture);
|
| + OverlayResourceNoLongerInUse(response.texture);
|
| }
|
| }
|
| }
|
| @@ -3690,4 +3690,94 @@ void GLRenderer::ScheduleOverlays(DrawingFrame* frame) {
|
| }
|
| }
|
|
|
| +void GLRenderer::OverlayResourceNoLongerInUse(GLuint texture) {
|
| + auto it = swapped_and_acked_overlay_resources_.find(texture);
|
| + std::vector<ResourceId> resource_ids;
|
| + if (it != swapped_and_acked_overlay_resources_.end()) {
|
| + resource_ids.push_back(it->second->resource_id());
|
| + swapped_and_acked_overlay_resources_.erase(it);
|
| + }
|
| + ReleaseIOSurfaces(resource_ids);
|
| +}
|
| +
|
| +ResourceId GLRenderer::CreateOrReuseIOSurface(const gfx::Size& size) {
|
| + DCHECK(settings_->release_overlay_resources_after_gpu_query);
|
| + for (auto it = free_iosurfaces_.begin(); it != free_iosurfaces_.end(); ++it) {
|
| + if ((*it)->size() == size) {
|
| + ResourceId id = (*it)->id();
|
| + in_use_iosurfaces_.emplace_back(std::move(*it));
|
| + free_iosurfaces_.erase(it);
|
| + return id;
|
| + }
|
| + }
|
| +
|
| + // TODO(erikchen): Update ScopedResouce to support IOSurface creation. This
|
| + // code doesn't actually make an IOSurface. https://crbug.com/581526.
|
| + std::unique_ptr<ScopedResource> resource =
|
| + ScopedResource::Create(resource_provider_);
|
| + resource->AllocateWithGpuMemoryBuffer(size, ResourceFormat::RGBA_8888);
|
| + ResourceId id = resource->id();
|
| + in_use_iosurfaces_.emplace_back(std::move(resource));
|
| + return id;
|
| +}
|
| +
|
| +void GLRenderer::DeleteIOSurfacesOverCacheLimit() {
|
| + if (free_iosurfaces_.size() > iosurface_limit_) {
|
| + size_t num_to_erase = free_iosurfaces_.size() - iosurface_limit_;
|
| + free_iosurfaces_.erase(free_iosurfaces_.begin(),
|
| + free_iosurfaces_.begin() + num_to_erase);
|
| + }
|
| +}
|
| +
|
| +bool GLRenderer::CopyRenderPassDrawQuadToIOSurface(
|
| + const RenderPassDrawQuad* quad,
|
| + ResourceId* resource_id) {
|
| + ScopedResource* contents_texture =
|
| + render_pass_textures_[quad->render_pass_id].get();
|
| + DCHECK(contents_texture);
|
| + DCHECK(contents_texture->id());
|
| + *resource_id = CreateOrReuseIOSurface(contents_texture->size());
|
| + ResourceProvider::ScopedWriteLockGL destination(resource_provider_,
|
| + *resource_id, false);
|
| +
|
| + GLuint source_texture = 0;
|
| + std::unique_ptr<ResourceProvider::ScopedReadLockGL> source;
|
| + if (current_framebuffer_lock_ &&
|
| + current_framebuffer_lock_->texture_id() == contents_texture->id()) {
|
| + source_texture = current_framebuffer_lock_->texture_id();
|
| + } else {
|
| + source.reset(new ResourceProvider::ScopedReadLockGL(
|
| + resource_provider_, contents_texture->id()));
|
| + source_texture = source->texture_id();
|
| + }
|
| + gl_->CopySubTextureCHROMIUM(source_texture, destination.texture_id(), 0, 0, 0,
|
| + 0, contents_texture->size().width(),
|
| + contents_texture->size().height(), GL_TRUE,
|
| + GL_FALSE, GL_FALSE);
|
| + return true;
|
| +}
|
| +
|
| +void GLRenderer::ReleaseIOSurfaces(const std::vector<ResourceId>& resources) {
|
| + if (in_use_iosurfaces_.empty() || resources.empty())
|
| + return;
|
| +
|
| + // Move all IOSurfaces that match resources to the end of in_use_iosurfaces_.
|
| + for (auto it = in_use_iosurfaces_.rbegin(); it != in_use_iosurfaces_.rend();
|
| + ++it) {
|
| + if (std::find(resources.begin(), resources.end(), (*it)->id()) !=
|
| + resources.end()) {
|
| + free_iosurfaces_.emplace_back(std::move(*it));
|
| + in_use_iosurfaces_.erase(std::next(it).base());
|
| + }
|
| + }
|
| +
|
| + DeleteIOSurfacesOverCacheLimit();
|
| +}
|
| +
|
| +void GLRenderer::UpdateCopyCountForFrame(size_t count) {
|
| + // Keep two frames worth of cached IOSurfaces.
|
| + iosurface_limit_ = count * 2;
|
| + DeleteIOSurfacesOverCacheLimit();
|
| +}
|
| +
|
| } // namespace cc
|
|
|