mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Previously, we were creating a new texture for every frame. Using tracing on a Nexus 5, that appears to cost about 6ms per frame on the GPU thread. After this CL, we keep a cache of recently used textures and only allocate a new one when either (1) we don't have one free or (2) our size requirements have changed. If our size requirements change, we dump the whole texture cache. In the future, we'll probably need something fancier if we ever need more than one size texture per frame. R=jamesr@chromium.org Review URL: https://codereview.chromium.org/845963006
101 lines
3.4 KiB
C++
101 lines
3.4 KiB
C++
// Copyright 2014 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "sky/compositor/resource_manager.h"
|
|
|
|
#ifndef GL_GLEXT_PROTOTYPES
|
|
#define GL_GLEXT_PROTOTYPES
|
|
#endif
|
|
|
|
#include "base/logging.h"
|
|
#include "base/stl_util.h"
|
|
#include "gpu/GLES2/gl2chromium.h"
|
|
#include "gpu/GLES2/gl2extchromium.h"
|
|
#include "mojo/converters/geometry/geometry_type_converters.h"
|
|
#include "mojo/gpu/gl_context.h"
|
|
#include "mojo/gpu/gl_texture.h"
|
|
#include "mojo/public/c/gles2/gles2.h"
|
|
#include "sky/compositor/layer.h"
|
|
|
|
namespace sky {
|
|
|
|
ResourceManager::ResourceManager(base::WeakPtr<mojo::GLContext> gl_context)
|
|
: gl_context_(gl_context), next_resource_id_(0) {
|
|
}
|
|
|
|
ResourceManager::~ResourceManager() {
|
|
STLDeleteContainerPairSecondPointers(resource_to_texture_map_.begin(),
|
|
resource_to_texture_map_.end());
|
|
}
|
|
|
|
scoped_ptr<mojo::GLTexture> ResourceManager::CreateTexture(
|
|
const gfx::Size& size) {
|
|
if (!available_textures_.empty()) {
|
|
scoped_ptr<mojo::GLTexture> texture(available_textures_.back());
|
|
available_textures_.back() = nullptr;
|
|
available_textures_.pop_back();
|
|
if (texture->size() == size)
|
|
return texture.Pass();
|
|
// Currently we only support caching textures of a constant size.
|
|
available_textures_.clear();
|
|
}
|
|
|
|
gl_context_->MakeCurrent();
|
|
return make_scoped_ptr(new mojo::GLTexture(
|
|
gl_context_, mojo::TypeConverter<mojo::Size, gfx::Size>::Convert(size)));
|
|
}
|
|
|
|
mojo::TransferableResourcePtr ResourceManager::CreateTransferableResource(
|
|
Layer* layer) {
|
|
scoped_ptr<mojo::GLTexture> texture = layer->GetTexture();
|
|
mojo::Size size = texture->size();
|
|
|
|
gl_context_->MakeCurrent();
|
|
glBindTexture(GL_TEXTURE_2D, texture->texture_id());
|
|
GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
|
|
glGenMailboxCHROMIUM(mailbox);
|
|
glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
|
|
GLuint sync_point = glInsertSyncPointCHROMIUM();
|
|
|
|
mojo::TransferableResourcePtr resource = mojo::TransferableResource::New();
|
|
resource->id = next_resource_id_++;
|
|
resource_to_texture_map_[resource->id] = texture.release();
|
|
resource->format = mojo::RESOURCE_FORMAT_RGBA_8888;
|
|
resource->filter = GL_LINEAR;
|
|
resource->size = size.Clone();
|
|
resource->is_repeated = false;
|
|
resource->is_software = false;
|
|
|
|
mojo::MailboxHolderPtr mailbox_holder = mojo::MailboxHolder::New();
|
|
mailbox_holder->mailbox = mojo::Mailbox::New();
|
|
for (int i = 0; i < GL_MAILBOX_SIZE_CHROMIUM; ++i)
|
|
mailbox_holder->mailbox->name.push_back(mailbox[i]);
|
|
mailbox_holder->texture_target = GL_TEXTURE_2D;
|
|
mailbox_holder->sync_point = sync_point;
|
|
resource->mailbox_holder = mailbox_holder.Pass();
|
|
|
|
return resource.Pass();
|
|
}
|
|
|
|
void ResourceManager::ReturnResources(
|
|
mojo::Array<mojo::ReturnedResourcePtr> resources) {
|
|
DCHECK(resources.size());
|
|
|
|
gl_context_->MakeCurrent();
|
|
for (size_t i = 0u; i < resources.size(); ++i) {
|
|
mojo::ReturnedResourcePtr resource = resources[i].Pass();
|
|
DCHECK_EQ(1, resource->count);
|
|
auto iter = resource_to_texture_map_.find(resource->id);
|
|
if (iter == resource_to_texture_map_.end())
|
|
continue;
|
|
mojo::GLTexture* texture = iter->second;
|
|
DCHECK_NE(0u, texture->texture_id());
|
|
resource_to_texture_map_.erase(iter);
|
|
glWaitSyncPointCHROMIUM(resource->sync_point);
|
|
available_textures_.push_back(texture);
|
|
}
|
|
}
|
|
|
|
} // namespace examples
|