diff options
author | Zeno Albisser <zeno.albisser@digia.com> | 2013-11-21 14:09:57 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2013-11-29 15:14:36 +0100 |
commit | eb32ba6f51d0c21d58cd7d89785285ff8fa64624 (patch) | |
tree | 2c7c940e1dbee81b89d935626110816b494aa32c /chromium/cc | |
parent | 9427c1a0222ebd67efef1a2c7990a0fa5c9aac84 (diff) | |
download | qtwebengine-chromium-eb32ba6f51d0c21d58cd7d89785285ff8fa64624.tar.gz |
Update chromium to branch 1599.
Change-Id: I04e775a946a208bb4500d3b722bcb05c82b9d7cb
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/cc')
42 files changed, 548 insertions, 2073 deletions
diff --git a/chromium/cc/cc.gyp b/chromium/cc/cc.gyp index e6e03c49899..78060a4175c 100644 --- a/chromium/cc/cc.gyp +++ b/chromium/cc/cc.gyp @@ -86,10 +86,6 @@ 'debug/rendering_stats_instrumentation.cc', 'debug/rendering_stats_instrumentation.h', 'debug/ring_buffer.h', - 'debug/test_context_provider.cc', - 'debug/test_context_provider.h', - 'debug/test_web_graphics_context_3d.cc', - 'debug/test_web_graphics_context_3d.h', 'debug/traced_picture.cc', 'debug/traced_picture.h', 'debug/traced_value.cc', diff --git a/chromium/cc/cc_tests.gyp b/chromium/cc/cc_tests.gyp index 4e4f4382e2c..7e2ff87f574 100644 --- a/chromium/cc/cc_tests.gyp +++ b/chromium/cc/cc_tests.gyp @@ -100,6 +100,8 @@ 'test/fake_content_layer_client.h', 'test/fake_content_layer_impl.cc', 'test/fake_content_layer_impl.h', + 'test/fake_context_provider.cc', + 'test/fake_context_provider.h', 'test/fake_delegated_renderer_layer.cc', 'test/fake_delegated_renderer_layer.h', 'test/fake_delegated_renderer_layer_impl.cc', @@ -172,6 +174,8 @@ 'test/skia_common.h', 'test/test_tile_priorities.cc', 'test/test_tile_priorities.h', + 'test/test_web_graphics_context_3d.cc', + 'test/test_web_graphics_context_3d.h', 'test/tiled_layer_test_common.cc', 'test/tiled_layer_test_common.h', ], diff --git a/chromium/cc/debug/test_context_provider.cc b/chromium/cc/debug/test_context_provider.cc deleted file mode 100644 index 4a3a2fcee2f..00000000000 --- a/chromium/cc/debug/test_context_provider.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2013 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 "cc/debug/test_context_provider.h" - -#include "base/logging.h" -#include "cc/debug/test_web_graphics_context_3d.h" - -namespace cc { - -// static -scoped_refptr<TestContextProvider> TestContextProvider::Create() { - return Create(TestWebGraphicsContext3D::CreateFactory()); -} - -// static -scoped_refptr<TestContextProvider> TestContextProvider::Create( - const CreateCallback& create_callback) { - scoped_refptr<TestContextProvider> provider = new TestContextProvider; - if (!provider->InitializeOnMainThread(create_callback)) - return NULL; - return provider; -} - -TestContextProvider::TestContextProvider() - : bound_(false), - destroyed_(false) { - DCHECK(main_thread_checker_.CalledOnValidThread()); - context_thread_checker_.DetachFromThread(); -} - -TestContextProvider::~TestContextProvider() { - DCHECK(main_thread_checker_.CalledOnValidThread() || - context_thread_checker_.CalledOnValidThread()); -} - -bool TestContextProvider::InitializeOnMainThread( - const CreateCallback& create_callback) { - DCHECK(main_thread_checker_.CalledOnValidThread()); - - DCHECK(!context3d_); - DCHECK(!create_callback.is_null()); - context3d_ = create_callback.Run(); - return context3d_; -} - -bool TestContextProvider::BindToCurrentThread() { - DCHECK(context3d_); - - // This is called on the thread the context will be used. - DCHECK(context_thread_checker_.CalledOnValidThread()); - - if (bound_) - return true; - - bound_ = true; - if (!context3d_->makeContextCurrent()) { - base::AutoLock lock(destroyed_lock_); - destroyed_ = true; - return false; - } - return true; -} - -WebKit::WebGraphicsContext3D* TestContextProvider::Context3d() { - DCHECK(context3d_); - DCHECK(bound_); - DCHECK(context_thread_checker_.CalledOnValidThread()); - - return context3d_.get(); -} - -class GrContext* TestContextProvider::GrContext() { - DCHECK(context3d_); - DCHECK(bound_); - DCHECK(context_thread_checker_.CalledOnValidThread()); - - // TODO(danakj): Make a test GrContext that works with a test Context3d. - return NULL; -} - -void TestContextProvider::VerifyContexts() { - DCHECK(context3d_); - DCHECK(bound_); - DCHECK(context_thread_checker_.CalledOnValidThread()); - - if (context3d_->isContextLost()) { - base::AutoLock lock(destroyed_lock_); - destroyed_ = true; - } -} - -bool TestContextProvider::DestroyedOnMainThread() { - DCHECK(main_thread_checker_.CalledOnValidThread()); - - base::AutoLock lock(destroyed_lock_); - return destroyed_; -} - -void TestContextProvider::SetLostContextCallback( - const LostContextCallback& cb) { - DCHECK(context_thread_checker_.CalledOnValidThread()); - NOTIMPLEMENTED(); -} - -} // namespace cc diff --git a/chromium/cc/debug/test_context_provider.h b/chromium/cc/debug/test_context_provider.h deleted file mode 100644 index 3a95bfbbcb7..00000000000 --- a/chromium/cc/debug/test_context_provider.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 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. - -#ifndef CC_DEBUG_TEST_CONTEXT_PROVIDER_H_ -#define CC_DEBUG_TEST_CONTEXT_PROVIDER_H_ - -#include "base/callback.h" -#include "base/memory/scoped_ptr.h" -#include "base/synchronization/lock.h" -#include "base/threading/thread_checker.h" -#include "cc/base/cc_export.h" -#include "cc/output/context_provider.h" - -namespace WebKit { class WebGraphicsContext3D; } - -namespace cc { -class TestWebGraphicsContext3D; - -class CC_EXPORT TestContextProvider - : public NON_EXPORTED_BASE(cc::ContextProvider) { - public: - typedef base::Callback<scoped_ptr<TestWebGraphicsContext3D>(void)> - CreateCallback; - - static scoped_refptr<TestContextProvider> Create(); - static scoped_refptr<TestContextProvider> Create( - const CreateCallback& create_callback); - - virtual bool BindToCurrentThread() OVERRIDE; - virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE; - virtual class GrContext* GrContext() OVERRIDE; - virtual void VerifyContexts() OVERRIDE; - virtual bool DestroyedOnMainThread() OVERRIDE; - virtual void SetLostContextCallback(const LostContextCallback& cb) OVERRIDE; - - TestWebGraphicsContext3D* TestContext3d() { return context3d_.get(); } - - protected: - TestContextProvider(); - virtual ~TestContextProvider(); - - bool InitializeOnMainThread(const CreateCallback& create_callback); - - scoped_ptr<TestWebGraphicsContext3D> context3d_; - bool bound_; - - base::ThreadChecker main_thread_checker_; - base::ThreadChecker context_thread_checker_; - - base::Lock destroyed_lock_; - bool destroyed_; -}; - -} // namespace cc - -#endif // CC_DEBUG_TEST_CONTEXT_PROVIDER_H_ - diff --git a/chromium/cc/debug/test_web_graphics_context_3d.cc b/chromium/cc/debug/test_web_graphics_context_3d.cc deleted file mode 100644 index 229ef636de3..00000000000 --- a/chromium/cc/debug/test_web_graphics_context_3d.cc +++ /dev/null @@ -1,654 +0,0 @@ -// Copyright 2013 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 "cc/debug/test_web_graphics_context_3d.h" - -#include <algorithm> -#include <string> - -#include "base/bind.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "gpu/GLES2/gl2extchromium.h" -#include "third_party/khronos/GLES2/gl2ext.h" - -using WebKit::WGC3Dboolean; -using WebKit::WGC3Dchar; -using WebKit::WGC3Denum; -using WebKit::WGC3Dint; -using WebKit::WGC3Dsizei; -using WebKit::WGC3Dsizeiptr; -using WebKit::WGC3Duint; -using WebKit::WebGLId; -using WebKit::WebGraphicsContext3D; - -namespace cc { - -static const WebGLId kFramebufferId = 1; -static const WebGLId kProgramId = 2; -static const WebGLId kRenderbufferId = 3; -static const WebGLId kShaderId = 4; - -static unsigned s_context_id = 1; - -const WebGLId TestWebGraphicsContext3D::kExternalTextureId = 1337; - -static base::LazyInstance<base::Lock>::Leaky - g_shared_namespace_lock = LAZY_INSTANCE_INITIALIZER; - -TestWebGraphicsContext3D::Namespace* - TestWebGraphicsContext3D::shared_namespace_ = NULL; - -TestWebGraphicsContext3D::Namespace::Namespace() - : next_buffer_id(1), - next_image_id(1), - next_texture_id(1) { -} - -TestWebGraphicsContext3D::Namespace::~Namespace() { - g_shared_namespace_lock.Get().AssertAcquired(); - if (shared_namespace_ == this) - shared_namespace_ = NULL; -} - -// static -scoped_ptr<TestWebGraphicsContext3D> TestWebGraphicsContext3D::Create() { - return make_scoped_ptr(new TestWebGraphicsContext3D()); -} - -// static -base::Callback<scoped_ptr<TestWebGraphicsContext3D>()> -TestWebGraphicsContext3D::CreateFactory() { - return base::Bind(&TestWebGraphicsContext3D::Create); -} - -TestWebGraphicsContext3D::TestWebGraphicsContext3D() - : FakeWebGraphicsContext3D(), - context_id_(s_context_id++), - support_swapbuffers_complete_callback_(true), - have_extension_io_surface_(false), - have_extension_egl_image_(false), - times_make_current_succeeds_(-1), - times_bind_texture_succeeds_(-1), - times_end_query_succeeds_(-1), - times_gen_mailbox_succeeds_(-1), - context_lost_(false), - times_map_image_chromium_succeeds_(-1), - times_map_buffer_chromium_succeeds_(-1), - context_lost_callback_(NULL), - swap_buffers_callback_(NULL), - memory_allocation_changed_callback_(NULL), - max_texture_size_(1024), - width_(0), - height_(0), - bound_buffer_(0), - weak_ptr_factory_(this) { - CreateNamespace(); -} - -TestWebGraphicsContext3D::TestWebGraphicsContext3D( - const WebGraphicsContext3D::Attributes& attributes) - : FakeWebGraphicsContext3D(), - context_id_(s_context_id++), - attributes_(attributes), - support_swapbuffers_complete_callback_(true), - have_extension_io_surface_(false), - have_extension_egl_image_(false), - times_make_current_succeeds_(-1), - times_bind_texture_succeeds_(-1), - times_end_query_succeeds_(-1), - times_gen_mailbox_succeeds_(-1), - context_lost_(false), - times_map_image_chromium_succeeds_(-1), - times_map_buffer_chromium_succeeds_(-1), - context_lost_callback_(NULL), - swap_buffers_callback_(NULL), - memory_allocation_changed_callback_(NULL), - max_texture_size_(1024), - width_(0), - height_(0), - bound_buffer_(0), - weak_ptr_factory_(this) { - CreateNamespace(); -} - -void TestWebGraphicsContext3D::CreateNamespace() { - if (attributes_.shareResources) { - base::AutoLock lock(g_shared_namespace_lock.Get()); - if (shared_namespace_) { - namespace_ = shared_namespace_; - } else { - namespace_ = new Namespace; - shared_namespace_ = namespace_.get(); - } - } else { - namespace_ = new Namespace; - } -} - -TestWebGraphicsContext3D::~TestWebGraphicsContext3D() { - for (size_t i = 0; i < sync_point_callbacks_.size(); ++i) { - if (sync_point_callbacks_[i] != NULL) - delete sync_point_callbacks_[i]; - } - base::AutoLock lock(g_shared_namespace_lock.Get()); - namespace_ = NULL; -} - -bool TestWebGraphicsContext3D::makeContextCurrent() { - if (times_make_current_succeeds_ >= 0) { - if (!times_make_current_succeeds_) { - loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, - GL_INNOCENT_CONTEXT_RESET_ARB); - } - --times_make_current_succeeds_; - } - return !context_lost_; -} - -int TestWebGraphicsContext3D::width() { - return width_; -} - -int TestWebGraphicsContext3D::height() { - return height_; -} - -void TestWebGraphicsContext3D::reshapeWithScaleFactor( - int width, int height, float scale_factor) { - width_ = width; - height_ = height; -} - -bool TestWebGraphicsContext3D::isContextLost() { - return context_lost_; -} - -WGC3Denum TestWebGraphicsContext3D::getGraphicsResetStatusARB() { - return context_lost_ ? GL_UNKNOWN_CONTEXT_RESET_ARB : GL_NO_ERROR; -} - -WGC3Denum TestWebGraphicsContext3D::checkFramebufferStatus( - WGC3Denum target) { - if (context_lost_) - return GL_FRAMEBUFFER_UNDEFINED_OES; - return GL_FRAMEBUFFER_COMPLETE; -} - -WebGraphicsContext3D::Attributes - TestWebGraphicsContext3D::getContextAttributes() { - return attributes_; -} - -WebKit::WebString TestWebGraphicsContext3D::getString(WGC3Denum name) { - std::string string; - - if (support_swapbuffers_complete_callback_) - string += "GL_CHROMIUM_swapbuffers_complete_callback"; - - if (name == GL_EXTENSIONS) { - if (have_extension_io_surface_) - string += " GL_CHROMIUM_iosurface GL_ARB_texture_rectangle"; - if (have_extension_egl_image_) - string += " GL_OES_EGL_image_external"; - } - - return WebKit::WebString::fromUTF8(string.c_str()); -} - -WGC3Dint TestWebGraphicsContext3D::getUniformLocation( - WebGLId program, - const WGC3Dchar* name) { - return 0; -} - -WGC3Dsizeiptr TestWebGraphicsContext3D::getVertexAttribOffset( - WGC3Duint index, - WGC3Denum pname) { - return 0; -} - -WGC3Dboolean TestWebGraphicsContext3D::isBuffer( - WebGLId buffer) { - return false; -} - -WGC3Dboolean TestWebGraphicsContext3D::isEnabled( - WGC3Denum cap) { - return false; -} - -WGC3Dboolean TestWebGraphicsContext3D::isFramebuffer( - WebGLId framebuffer) { - return false; -} - -WGC3Dboolean TestWebGraphicsContext3D::isProgram( - WebGLId program) { - return false; -} - -WGC3Dboolean TestWebGraphicsContext3D::isRenderbuffer( - WebGLId renderbuffer) { - return false; -} - -WGC3Dboolean TestWebGraphicsContext3D::isShader( - WebGLId shader) { - return false; -} - -WGC3Dboolean TestWebGraphicsContext3D::isTexture( - WebGLId texture) { - return false; -} - -WebGLId TestWebGraphicsContext3D::createBuffer() { - return NextBufferId(); -} - -void TestWebGraphicsContext3D::deleteBuffer(WebGLId id) { - base::AutoLock lock(namespace_->lock); - unsigned context_id = id >> 17; - unsigned buffer_id = id & 0x1ffff; - DCHECK(buffer_id && buffer_id < namespace_->next_buffer_id); - DCHECK_EQ(context_id, context_id_); -} - -WebGLId TestWebGraphicsContext3D::createFramebuffer() { - return kFramebufferId | context_id_ << 16; -} - -void TestWebGraphicsContext3D::deleteFramebuffer(WebGLId id) { - DCHECK_EQ(kFramebufferId | context_id_ << 16, id); -} - -WebGLId TestWebGraphicsContext3D::createProgram() { - return kProgramId | context_id_ << 16; -} - -void TestWebGraphicsContext3D::deleteProgram(WebGLId id) { - DCHECK_EQ(kProgramId | context_id_ << 16, id); -} - -WebGLId TestWebGraphicsContext3D::createRenderbuffer() { - return kRenderbufferId | context_id_ << 16; -} - -void TestWebGraphicsContext3D::deleteRenderbuffer(WebGLId id) { - DCHECK_EQ(kRenderbufferId | context_id_ << 16, id); -} - -WebGLId TestWebGraphicsContext3D::createShader(WGC3Denum) { - return kShaderId | context_id_ << 16; -} - -void TestWebGraphicsContext3D::deleteShader(WebGLId id) { - DCHECK_EQ(kShaderId | context_id_ << 16, id); -} - -WebGLId TestWebGraphicsContext3D::createTexture() { - WebGLId texture_id = NextTextureId(); - DCHECK_NE(texture_id, kExternalTextureId); - base::AutoLock lock(namespace_->lock); - namespace_->textures.push_back(texture_id); - return texture_id; -} - -void TestWebGraphicsContext3D::deleteTexture(WebGLId texture_id) { - base::AutoLock lock(namespace_->lock); - std::vector<WebKit::WebGLId>& textures = namespace_->textures; - DCHECK(std::find(textures.begin(), textures.end(), texture_id) != - textures.end()); - textures.erase(std::find(textures.begin(), textures.end(), texture_id)); -} - -void TestWebGraphicsContext3D::attachShader(WebGLId program, WebGLId shader) { - DCHECK_EQ(kProgramId | context_id_ << 16, program); - DCHECK_EQ(kShaderId | context_id_ << 16, shader); -} - -void TestWebGraphicsContext3D::useProgram(WebGLId program) { - if (!program) - return; - DCHECK_EQ(kProgramId | context_id_ << 16, program); -} - -void TestWebGraphicsContext3D::bindFramebuffer( - WGC3Denum target, WebGLId framebuffer) { - if (!framebuffer) - return; - DCHECK_EQ(kFramebufferId | context_id_ << 16, framebuffer); -} - -void TestWebGraphicsContext3D::bindRenderbuffer( - WGC3Denum target, WebGLId renderbuffer) { - if (!renderbuffer) - return; - DCHECK_EQ(kRenderbufferId | context_id_ << 16, renderbuffer); -} - -void TestWebGraphicsContext3D::bindTexture( - WGC3Denum target, WebGLId texture_id) { - if (times_bind_texture_succeeds_ >= 0) { - if (!times_bind_texture_succeeds_) { - loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, - GL_INNOCENT_CONTEXT_RESET_ARB); - } - --times_bind_texture_succeeds_; - } - - if (!texture_id) - return; - if (texture_id == kExternalTextureId) - return; - base::AutoLock lock(namespace_->lock); - std::vector<WebKit::WebGLId>& textures = namespace_->textures; - DCHECK(std::find(textures.begin(), textures.end(), texture_id) != - textures.end()); - used_textures_.insert(texture_id); -} - -void TestWebGraphicsContext3D::endQueryEXT(WGC3Denum target) { - if (times_end_query_succeeds_ >= 0) { - if (!times_end_query_succeeds_) { - loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, - GL_INNOCENT_CONTEXT_RESET_ARB); - } - --times_end_query_succeeds_; - } -} - -void TestWebGraphicsContext3D::getQueryObjectuivEXT( - WebGLId query, - WGC3Denum pname, - WGC3Duint* params) { - // If the context is lost, behave as if result is available. - if (pname == GL_QUERY_RESULT_AVAILABLE_EXT) - *params = 1; -} - -void TestWebGraphicsContext3D::getIntegerv( - WGC3Denum pname, - WebKit::WGC3Dint* value) { - if (pname == GL_MAX_TEXTURE_SIZE) - *value = max_texture_size_; - else if (pname == GL_ACTIVE_TEXTURE) - *value = GL_TEXTURE0; -} - -void TestWebGraphicsContext3D::genMailboxCHROMIUM(WebKit::WGC3Dbyte* mailbox) { - if (times_gen_mailbox_succeeds_ >= 0) { - if (!times_gen_mailbox_succeeds_) { - loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, - GL_INNOCENT_CONTEXT_RESET_ARB); - } - --times_gen_mailbox_succeeds_; - } - if (context_lost_) { - memset(mailbox, 0, 64); - return; - } - - static char mailbox_name1 = '1'; - static char mailbox_name2 = '1'; - mailbox[0] = mailbox_name1; - mailbox[1] = mailbox_name2; - mailbox[2] = '\0'; - if (++mailbox_name1 == 0) { - mailbox_name1 = '1'; - ++mailbox_name2; - } -} - -void TestWebGraphicsContext3D::setContextLostCallback( - WebGraphicsContextLostCallback* callback) { - context_lost_callback_ = callback; -} - -void TestWebGraphicsContext3D::loseContextCHROMIUM(WGC3Denum current, - WGC3Denum other) { - if (context_lost_) - return; - context_lost_ = true; - if (context_lost_callback_) - context_lost_callback_->onContextLost(); - - for (size_t i = 0; i < shared_contexts_.size(); ++i) - shared_contexts_[i]->loseContextCHROMIUM(current, other); - shared_contexts_.clear(); -} - -void TestWebGraphicsContext3D::signalSyncPoint( - unsigned sync_point, - WebGraphicsSyncPointCallback* callback) { - sync_point_callbacks_.push_back(callback); -} - -void TestWebGraphicsContext3D::signalQuery( - WebKit::WebGLId query, - WebGraphicsSyncPointCallback* callback) { - sync_point_callbacks_.push_back(callback); -} - -void TestWebGraphicsContext3D::setSwapBuffersCompleteCallbackCHROMIUM( - WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* callback) { - if (support_swapbuffers_complete_callback_) - swap_buffers_callback_ = callback; -} - -void TestWebGraphicsContext3D::setMemoryAllocationChangedCallbackCHROMIUM( - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) { - memory_allocation_changed_callback_ = callback; -} - -void TestWebGraphicsContext3D::prepareTexture() { - if (swap_buffers_callback_) { - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(&TestWebGraphicsContext3D::SwapBuffersComplete, - weak_ptr_factory_.GetWeakPtr())); - } - CallAllSyncPointCallbacks(); -} - -void TestWebGraphicsContext3D::finish() { - CallAllSyncPointCallbacks(); -} - -void TestWebGraphicsContext3D::flush() { - CallAllSyncPointCallbacks(); -} - -static void CallAndDestroy( - WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback* callback) { - if (!callback) - return; - callback->onSyncPointReached(); - delete callback; -} - -void TestWebGraphicsContext3D::CallAllSyncPointCallbacks() { - for (size_t i = 0; i < sync_point_callbacks_.size(); ++i) { - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&CallAndDestroy, - sync_point_callbacks_[i])); - } - sync_point_callbacks_.clear(); -} - -void TestWebGraphicsContext3D::SwapBuffersComplete() { - if (swap_buffers_callback_) - swap_buffers_callback_->onSwapBuffersComplete(); -} - -void TestWebGraphicsContext3D::bindBuffer(WebKit::WGC3Denum target, - WebKit::WebGLId buffer) { - bound_buffer_ = buffer; - if (!bound_buffer_) - return; - unsigned context_id = buffer >> 17; - unsigned buffer_id = buffer & 0x1ffff; - base::AutoLock lock(namespace_->lock); - DCHECK(buffer_id && buffer_id < namespace_->next_buffer_id); - DCHECK_EQ(context_id, context_id_); - - ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; - if (buffers.count(bound_buffer_) == 0) - buffers.set(bound_buffer_, make_scoped_ptr(new Buffer).Pass()); - - buffers.get(bound_buffer_)->target = target; -} - -void TestWebGraphicsContext3D::bufferData(WebKit::WGC3Denum target, - WebKit::WGC3Dsizeiptr size, - const void* data, - WebKit::WGC3Denum usage) { - base::AutoLock lock(namespace_->lock); - ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; - DCHECK_GT(buffers.count(bound_buffer_), 0u); - DCHECK_EQ(target, buffers.get(bound_buffer_)->target); - if (context_lost_) { - buffers.get(bound_buffer_)->pixels.reset(); - return; - } - buffers.get(bound_buffer_)->pixels.reset(new uint8[size]); - if (data != NULL) - memcpy(buffers.get(bound_buffer_)->pixels.get(), data, size); -} - -void* TestWebGraphicsContext3D::mapBufferCHROMIUM(WebKit::WGC3Denum target, - WebKit::WGC3Denum access) { - base::AutoLock lock(namespace_->lock); - ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; - DCHECK_GT(buffers.count(bound_buffer_), 0u); - DCHECK_EQ(target, buffers.get(bound_buffer_)->target); - if (times_map_buffer_chromium_succeeds_ >= 0) { - if (!times_map_buffer_chromium_succeeds_) { - return NULL; - } - --times_map_buffer_chromium_succeeds_; - } - return buffers.get(bound_buffer_)->pixels.get(); -} - -WebKit::WGC3Dboolean TestWebGraphicsContext3D::unmapBufferCHROMIUM( - WebKit::WGC3Denum target) { - base::AutoLock lock(namespace_->lock); - ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; - DCHECK_GT(buffers.count(bound_buffer_), 0u); - DCHECK_EQ(target, buffers.get(bound_buffer_)->target); - buffers.get(bound_buffer_)->pixels.reset(); - return true; -} - -void TestWebGraphicsContext3D::bindTexImage2DCHROMIUM( - WebKit::WGC3Denum target, - WebKit::WGC3Dint image_id) { - base::AutoLock lock(namespace_->lock); - DCHECK_GT(namespace_->images.count(image_id), 0u); -} - -WebKit::WGC3Duint TestWebGraphicsContext3D::createImageCHROMIUM( - WebKit::WGC3Dsizei width, WebKit::WGC3Dsizei height, - WebKit::WGC3Denum internalformat) { - DCHECK_EQ(GL_RGBA8_OES, static_cast<int>(internalformat)); - WebKit::WGC3Duint image_id = NextImageId(); - base::AutoLock lock(namespace_->lock); - ScopedPtrHashMap<unsigned, Image>& images = namespace_->images; - images.set(image_id, make_scoped_ptr(new Image).Pass()); - images.get(image_id)->pixels.reset(new uint8[width * height * 4]); - return image_id; -} - -void TestWebGraphicsContext3D::destroyImageCHROMIUM( - WebKit::WGC3Duint id) { - base::AutoLock lock(namespace_->lock); - unsigned context_id = id >> 17; - unsigned image_id = id & 0x1ffff; - DCHECK(image_id && image_id < namespace_->next_image_id); - DCHECK_EQ(context_id, context_id_); -} - -void TestWebGraphicsContext3D::getImageParameterivCHROMIUM( - WebKit::WGC3Duint image_id, - WebKit::WGC3Denum pname, - WebKit::WGC3Dint* params) { - base::AutoLock lock(namespace_->lock); - DCHECK_GT(namespace_->images.count(image_id), 0u); - DCHECK_EQ(GL_IMAGE_ROWBYTES_CHROMIUM, static_cast<int>(pname)); - *params = 0; -} - -void* TestWebGraphicsContext3D::mapImageCHROMIUM(WebKit::WGC3Duint image_id, - WebKit::WGC3Denum access) { - base::AutoLock lock(namespace_->lock); - ScopedPtrHashMap<unsigned, Image>& images = namespace_->images; - DCHECK_GT(images.count(image_id), 0u); - if (times_map_image_chromium_succeeds_ >= 0) { - if (!times_map_image_chromium_succeeds_) { - return NULL; - } - --times_map_image_chromium_succeeds_; - } - return images.get(image_id)->pixels.get(); -} - -void TestWebGraphicsContext3D::unmapImageCHROMIUM( - WebKit::WGC3Duint image_id) { - base::AutoLock lock(namespace_->lock); - DCHECK_GT(namespace_->images.count(image_id), 0u); -} - -size_t TestWebGraphicsContext3D::NumTextures() const { - base::AutoLock lock(namespace_->lock); - return namespace_->textures.size(); -} - -WebKit::WebGLId TestWebGraphicsContext3D::TextureAt(int i) const { - base::AutoLock lock(namespace_->lock); - return namespace_->textures[i]; -} - -WebGLId TestWebGraphicsContext3D::NextTextureId() { - base::AutoLock lock(namespace_->lock); - WebGLId texture_id = namespace_->next_texture_id++; - DCHECK(texture_id < (1 << 16)); - texture_id |= context_id_ << 16; - return texture_id; -} - -WebGLId TestWebGraphicsContext3D::NextBufferId() { - base::AutoLock lock(namespace_->lock); - WebGLId buffer_id = namespace_->next_buffer_id++; - DCHECK(buffer_id < (1 << 17)); - buffer_id |= context_id_ << 17; - return buffer_id; -} - -WebKit::WGC3Duint TestWebGraphicsContext3D::NextImageId() { - base::AutoLock lock(namespace_->lock); - WGC3Duint image_id = namespace_->next_image_id++; - DCHECK(image_id < (1 << 17)); - image_id |= context_id_ << 17; - return image_id; -} - -void TestWebGraphicsContext3D::SetMemoryAllocation( - WebKit::WebGraphicsMemoryAllocation allocation) { - if (!memory_allocation_changed_callback_) - return; - memory_allocation_changed_callback_->onMemoryAllocationChanged(allocation); -} - -TestWebGraphicsContext3D::Buffer::Buffer() : target(0) {} - -TestWebGraphicsContext3D::Buffer::~Buffer() {} - -TestWebGraphicsContext3D::Image::Image() {} - -TestWebGraphicsContext3D::Image::~Image() {} - -} // namespace cc diff --git a/chromium/cc/debug/test_web_graphics_context_3d.h b/chromium/cc/debug/test_web_graphics_context_3d.h deleted file mode 100644 index e66a16552be..00000000000 --- a/chromium/cc/debug/test_web_graphics_context_3d.h +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright 2013 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. - -#ifndef CC_DEBUG_TEST_WEB_GRAPHICS_CONTEXT_3D_H_ -#define CC_DEBUG_TEST_WEB_GRAPHICS_CONTEXT_3D_H_ - -#include <vector> - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/stl_util.h" -#include "base/synchronization/lock.h" -#include "cc/base/cc_export.h" -#include "cc/base/scoped_ptr_hash_map.h" -#include "cc/debug/fake_web_graphics_context_3d.h" -#include "third_party/khronos/GLES2/gl2.h" - -namespace WebKit { struct WebGraphicsMemoryAllocation; } - -namespace cc { - -class CC_EXPORT TestWebGraphicsContext3D : public FakeWebGraphicsContext3D { - public: - static scoped_ptr<TestWebGraphicsContext3D> Create(); - static base::Callback< - scoped_ptr<TestWebGraphicsContext3D>()> CreateFactory(); - - virtual ~TestWebGraphicsContext3D(); - - virtual bool makeContextCurrent(); - - virtual int width(); - virtual int height(); - - virtual void reshapeWithScaleFactor( - int width, int height, float scale_factor); - - virtual bool isContextLost(); - virtual WebKit::WGC3Denum getGraphicsResetStatusARB(); - - virtual void attachShader(WebKit::WebGLId program, WebKit::WebGLId shader); - virtual void bindFramebuffer( - WebKit::WGC3Denum target, WebKit::WebGLId framebuffer); - virtual void bindRenderbuffer( - WebKit::WGC3Denum target, WebKit::WebGLId renderbuffer); - virtual void bindTexture( - WebKit::WGC3Denum target, - WebKit::WebGLId texture_id); - - virtual WebKit::WGC3Denum checkFramebufferStatus(WebKit::WGC3Denum target); - - virtual Attributes getContextAttributes(); - - virtual WebKit::WebString getString(WebKit::WGC3Denum name); - virtual WebKit::WGC3Dint getUniformLocation( - WebKit::WebGLId program, - const WebKit::WGC3Dchar* name); - virtual WebKit::WGC3Dsizeiptr getVertexAttribOffset( - WebKit::WGC3Duint index, - WebKit::WGC3Denum pname); - - virtual WebKit::WGC3Dboolean isBuffer(WebKit::WebGLId buffer); - virtual WebKit::WGC3Dboolean isEnabled(WebKit::WGC3Denum cap); - virtual WebKit::WGC3Dboolean isFramebuffer(WebKit::WebGLId framebuffer); - virtual WebKit::WGC3Dboolean isProgram(WebKit::WebGLId program); - virtual WebKit::WGC3Dboolean isRenderbuffer(WebKit::WebGLId renderbuffer); - virtual WebKit::WGC3Dboolean isShader(WebKit::WebGLId shader); - virtual WebKit::WGC3Dboolean isTexture(WebKit::WebGLId texture); - - virtual void useProgram(WebKit::WebGLId program); - - virtual WebKit::WebGLId createBuffer(); - virtual WebKit::WebGLId createFramebuffer(); - virtual WebKit::WebGLId createProgram(); - virtual WebKit::WebGLId createRenderbuffer(); - virtual WebKit::WebGLId createShader(WebKit::WGC3Denum); - virtual WebKit::WebGLId createTexture(); - - virtual void deleteBuffer(WebKit::WebGLId id); - virtual void deleteFramebuffer(WebKit::WebGLId id); - virtual void deleteProgram(WebKit::WebGLId id); - virtual void deleteRenderbuffer(WebKit::WebGLId id); - virtual void deleteShader(WebKit::WebGLId id); - virtual void deleteTexture(WebKit::WebGLId texture_id); - - virtual void endQueryEXT(WebKit::WGC3Denum target); - virtual void getQueryObjectuivEXT( - WebKit::WebGLId query, - WebKit::WGC3Denum pname, - WebKit::WGC3Duint* params); - - virtual void getIntegerv( - WebKit::WGC3Denum pname, - WebKit::WGC3Dint* value); - - virtual void genMailboxCHROMIUM(WebKit::WGC3Dbyte* mailbox); - virtual void produceTextureCHROMIUM(WebKit::WGC3Denum target, - const WebKit::WGC3Dbyte* mailbox) { } - virtual void consumeTextureCHROMIUM(WebKit::WGC3Denum target, - const WebKit::WGC3Dbyte* mailbox) { } - - virtual void setContextLostCallback( - WebGraphicsContextLostCallback* callback); - - virtual void loseContextCHROMIUM(WebKit::WGC3Denum current, - WebKit::WGC3Denum other); - - // Takes ownership of the |callback|. - virtual void signalSyncPoint(unsigned sync_point, - WebGraphicsSyncPointCallback* callback); - virtual void signalQuery(WebKit::WebGLId query, - WebGraphicsSyncPointCallback* callback); - - virtual void setSwapBuffersCompleteCallbackCHROMIUM( - WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* callback); - - virtual void setMemoryAllocationChangedCallbackCHROMIUM( - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback); - - virtual void prepareTexture(); - virtual void finish(); - virtual void flush(); - - virtual void bindBuffer(WebKit::WGC3Denum target, WebKit::WebGLId buffer); - virtual void bufferData(WebKit::WGC3Denum target, - WebKit::WGC3Dsizeiptr size, - const void* data, - WebKit::WGC3Denum usage); - virtual void* mapBufferCHROMIUM(WebKit::WGC3Denum target, - WebKit::WGC3Denum access); - virtual WebKit::WGC3Dboolean unmapBufferCHROMIUM(WebKit::WGC3Denum target); - - virtual void bindTexImage2DCHROMIUM(WebKit::WGC3Denum target, - WebKit::WGC3Dint image_id); - virtual WebKit::WGC3Duint createImageCHROMIUM( - WebKit::WGC3Dsizei width, - WebKit::WGC3Dsizei height, - WebKit::WGC3Denum internalformat); - virtual void destroyImageCHROMIUM(WebKit::WGC3Duint image_id); - virtual void getImageParameterivCHROMIUM( - WebKit::WGC3Duint image_id, - WebKit::WGC3Denum pname, - WebKit::WGC3Dint* params); - virtual void* mapImageCHROMIUM( - WebKit::WGC3Duint image_id, - WebKit::WGC3Denum access); - virtual void unmapImageCHROMIUM(WebKit::WGC3Duint image_id); - - // When set, MakeCurrent() will fail after this many times. - void set_times_make_current_succeeds(int times) { - times_make_current_succeeds_ = times; - } - void set_times_bind_texture_succeeds(int times) { - times_bind_texture_succeeds_ = times; - } - void set_times_end_query_succeeds(int times) { - times_end_query_succeeds_ = times; - } - void set_times_gen_mailbox_succeeds(int times) { - times_gen_mailbox_succeeds_ = times; - } - - // When set, mapImageCHROMIUM and mapBufferCHROMIUM will return NULL after - // this many times. - void set_times_map_image_chromium_succeeds(int times) { - times_map_image_chromium_succeeds_ = times; - } - void set_times_map_buffer_chromium_succeeds(int times) { - times_map_buffer_chromium_succeeds_ = times; - } - - size_t NumTextures() const; - WebKit::WebGLId TextureAt(int i) const; - - size_t NumUsedTextures() const { return used_textures_.size(); } - bool UsedTexture(int texture) const { - return ContainsKey(used_textures_, texture); - } - void ResetUsedTextures() { used_textures_.clear(); } - - void set_support_swapbuffers_complete_callback(bool support) { - support_swapbuffers_complete_callback_ = support; - } - void set_have_extension_io_surface(bool have) { - have_extension_io_surface_ = have; - } - void set_have_extension_egl_image(bool have) { - have_extension_egl_image_ = have; - } - - // When this context is lost, all contexts in its share group are also lost. - void add_share_group_context(WebKit::WebGraphicsContext3D* context3d) { - shared_contexts_.push_back(context3d); - } - - void set_max_texture_size(int size) { max_texture_size_ = size; } - - static const WebKit::WebGLId kExternalTextureId; - virtual WebKit::WebGLId NextTextureId(); - - virtual WebKit::WebGLId NextBufferId(); - - virtual WebKit::WebGLId NextImageId(); - - void SetMemoryAllocation(WebKit::WebGraphicsMemoryAllocation allocation); - - protected: - struct Buffer { - Buffer(); - ~Buffer(); - - WebKit::WGC3Denum target; - scoped_ptr<uint8[]> pixels; - - private: - DISALLOW_COPY_AND_ASSIGN(Buffer); - }; - - struct Image { - Image(); - ~Image(); - - scoped_ptr<uint8[]> pixels; - - private: - DISALLOW_COPY_AND_ASSIGN(Image); - }; - - struct Namespace : public base::RefCountedThreadSafe<Namespace> { - Namespace(); - - // Protects all fields. - base::Lock lock; - unsigned next_buffer_id; - unsigned next_image_id; - unsigned next_texture_id; - std::vector<WebKit::WebGLId> textures; - ScopedPtrHashMap<unsigned, Buffer> buffers; - ScopedPtrHashMap<unsigned, Image> images; - - private: - friend class base::RefCountedThreadSafe<Namespace>; - ~Namespace(); - DISALLOW_COPY_AND_ASSIGN(Namespace); - }; - - TestWebGraphicsContext3D(); - TestWebGraphicsContext3D( - const WebKit::WebGraphicsContext3D::Attributes& attributes); - - void CallAllSyncPointCallbacks(); - void SwapBuffersComplete(); - void CreateNamespace(); - - unsigned context_id_; - Attributes attributes_; - bool support_swapbuffers_complete_callback_; - bool have_extension_io_surface_; - bool have_extension_egl_image_; - int times_make_current_succeeds_; - int times_bind_texture_succeeds_; - int times_end_query_succeeds_; - int times_gen_mailbox_succeeds_; - bool context_lost_; - int times_map_image_chromium_succeeds_; - int times_map_buffer_chromium_succeeds_; - WebGraphicsContextLostCallback* context_lost_callback_; - WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* swap_buffers_callback_; - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* - memory_allocation_changed_callback_; - std::vector<WebGraphicsSyncPointCallback*> sync_point_callbacks_; - base::hash_set<WebKit::WebGLId> used_textures_; - std::vector<WebKit::WebGraphicsContext3D*> shared_contexts_; - int max_texture_size_; - int width_; - int height_; - - unsigned bound_buffer_; - - scoped_refptr<Namespace> namespace_; - static Namespace* shared_namespace_; - - base::WeakPtrFactory<TestWebGraphicsContext3D> weak_ptr_factory_; -}; - -} // namespace cc - -#endif // CC_DEBUG_TEST_WEB_GRAPHICS_CONTEXT_3D_H_ diff --git a/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc b/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc index 2537c53053b..1584782f109 100644 --- a/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc +++ b/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc @@ -5,7 +5,6 @@ #include "cc/layers/delegated_renderer_layer_impl.h" #include "cc/base/scoped_ptr_vector.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/quad_sink.h" #include "cc/layers/solid_color_layer_impl.h" @@ -21,6 +20,7 @@ #include "cc/test/mock_quad_culler.h" #include "cc/test/render_pass_test_common.h" #include "cc/test/render_pass_test_utils.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc index 4f6052f04fa..2f1878bc3a6 100644 --- a/chromium/cc/layers/picture_layer_impl.cc +++ b/chromium/cc/layers/picture_layer_impl.cc @@ -617,24 +617,27 @@ void PictureLayerImpl::SetIsMask(bool is_mask) { ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const { gfx::Rect content_rect(content_bounds()); float scale = contents_scale_x(); - PictureLayerTilingSet::CoverageIterator iter( - tilings_.get(), scale, content_rect, ideal_contents_scale_); - - // Mask resource not ready yet. - if (!iter || !*iter) - return 0; + for (PictureLayerTilingSet::CoverageIterator + iter(tilings_.get(), scale, content_rect, ideal_contents_scale_); + iter; + ++iter) { + // Mask resource not ready yet. + if (!*iter) + return 0; - // Masks only supported if they fit on exactly one tile. - if (iter.geometry_rect() != content_rect) - return 0; + const ManagedTileState::TileVersion& tile_version = + iter->GetTileVersionForDrawing(); + if (!tile_version.IsReadyToDraw() || + tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE) + return 0; - const ManagedTileState::TileVersion& tile_version = - iter->GetTileVersionForDrawing(); - if (!tile_version.IsReadyToDraw() || - tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE) - return 0; + // Masks only supported if they fit on exactly one tile. + if (iter.geometry_rect() != content_rect) + return 0; - return tile_version.get_resource_id(); + return tile_version.get_resource_id(); + } + return 0; } void PictureLayerImpl::MarkVisibleResourcesAsRequired() const { diff --git a/chromium/cc/layers/scrollbar_layer.cc b/chromium/cc/layers/scrollbar_layer.cc index a2fdd58ee36..95eb6384732 100644 --- a/chromium/cc/layers/scrollbar_layer.cc +++ b/chromium/cc/layers/scrollbar_layer.cc @@ -1,3 +1,4 @@ + // Copyright 2012 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. @@ -8,15 +9,12 @@ #include "base/basictypes.h" #include "base/debug/trace_event.h" #include "cc/layers/scrollbar_layer_impl.h" -#include "cc/resources/ui_resource_bitmap.h" +#include "cc/resources/caching_bitmap_content_layer_updater.h" +#include "cc/resources/layer_painter.h" +#include "cc/resources/prioritized_resource.h" +#include "cc/resources/resource_update_queue.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_impl.h" -#include "skia/ext/platform_canvas.h" -#include "skia/ext/refptr.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkSize.h" -#include "ui/gfx/skia_util.h" +#include "ui/gfx/rect_conversions.h" namespace cc { @@ -29,15 +27,16 @@ scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl( scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create( scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id) { - return make_scoped_refptr( - new ScrollbarLayer(scrollbar.Pass(), scroll_layer_id)); + return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(), + scroll_layer_id)); } ScrollbarLayer::ScrollbarLayer( scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id) : scrollbar_(scrollbar.Pass()), - scroll_layer_id_(scroll_layer_id) { + scroll_layer_id_(scroll_layer_id), + texture_format_(GL_INVALID_ENUM) { if (!scrollbar_->IsOverlay()) SetShouldScrollOnMainThread(true); } @@ -122,17 +121,22 @@ void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { } scrollbar_layer->SetThumbLength(thumb_length_); if (Orientation() == HORIZONTAL) { - scrollbar_layer->SetTrackStart(track_rect_.x()); + scrollbar_layer->SetTrackStart(track_rect_.x() - location_.x()); scrollbar_layer->SetTrackLength(track_rect_.width()); } else { - scrollbar_layer->SetTrackStart(track_rect_.y()); + scrollbar_layer->SetTrackStart(track_rect_.y() - location_.y()); scrollbar_layer->SetTrackLength(track_rect_.height()); } - if (track_resource_.get()) - scrollbar_layer->set_track_ui_resource_id(track_resource_->id()); - if (thumb_resource_.get()) - scrollbar_layer->set_thumb_ui_resource_id(thumb_resource_->id()); + if (track_ && track_->texture()->have_backing_texture()) + scrollbar_layer->set_track_resource_id(track_->texture()->resource_id()); + else + scrollbar_layer->set_track_resource_id(0); + + if (thumb_ && thumb_->texture()->have_backing_texture()) + scrollbar_layer->set_thumb_resource_id(thumb_->texture()->resource_id()); + else + scrollbar_layer->set_thumb_resource_id(0); scrollbar_layer->set_is_overlay_scrollbar(scrollbar_->IsOverlay()); @@ -145,16 +149,113 @@ ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() { } void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { - // When the LTH is set to null or has changed, then this layer should remove - // all of its associated resources. if (!host || host != layer_tree_host()) { - track_resource_.reset(); - thumb_resource_.reset(); + track_updater_ = NULL; + track_.reset(); + thumb_updater_ = NULL; + thumb_.reset(); } ContentsScalingLayer::SetLayerTreeHost(host); } +class ScrollbarPartPainter : public LayerPainter { + public: + ScrollbarPartPainter(Scrollbar* scrollbar, ScrollbarPart part) + : scrollbar_(scrollbar), + part_(part) {} + virtual ~ScrollbarPartPainter() {} + + // LayerPainter implementation + virtual void Paint(SkCanvas* canvas, + gfx::Rect content_rect, + gfx::RectF* opaque) OVERRIDE { + scrollbar_->PaintPart(canvas, part_, content_rect); + } + + private: + Scrollbar* scrollbar_; + ScrollbarPart part_; +}; + +void ScrollbarLayer::CreateUpdaterIfNeeded() { + if (layer_tree_host()->settings().solid_color_scrollbars) + return; + + texture_format_ = + layer_tree_host()->GetRendererCapabilities().best_texture_format; + + if (!track_updater_.get()) { + track_updater_ = CachingBitmapContentLayerUpdater::Create( + scoped_ptr<LayerPainter>( + new ScrollbarPartPainter(scrollbar_.get(), TRACK)) + .Pass(), + rendering_stats_instrumentation(), + id()); + } + if (!track_) { + track_ = track_updater_->CreateResource( + layer_tree_host()->contents_texture_manager()); + } + + if (!thumb_updater_.get()) { + thumb_updater_ = CachingBitmapContentLayerUpdater::Create( + scoped_ptr<LayerPainter>( + new ScrollbarPartPainter(scrollbar_.get(), THUMB)) + .Pass(), + rendering_stats_instrumentation(), + id()); + } + if (!thumb_ && scrollbar_->HasThumb()) { + thumb_ = thumb_updater_->CreateResource( + layer_tree_host()->contents_texture_manager()); + } +} + +bool ScrollbarLayer::UpdatePart(CachingBitmapContentLayerUpdater* painter, + LayerUpdater::Resource* resource, + gfx::Rect rect, + ResourceUpdateQueue* queue) { + if (layer_tree_host()->settings().solid_color_scrollbars) + return false; + + // Skip painting and uploading if there are no invalidations and + // we already have valid texture data. + if (resource->texture()->have_backing_texture() && + resource->texture()->size() == rect.size() && + !is_dirty()) + return false; + + // We should always have enough memory for UI. + DCHECK(resource->texture()->can_acquire_backing_texture()); + if (!resource->texture()->can_acquire_backing_texture()) + return false; + + // Paint and upload the entire part. + gfx::Rect painted_opaque_rect; + painter->PrepareToUpdate(rect, + rect.size(), + contents_scale_x(), + contents_scale_y(), + &painted_opaque_rect); + if (!painter->pixels_did_change() && + resource->texture()->have_backing_texture()) { + TRACE_EVENT_INSTANT0("cc", + "ScrollbarLayer::UpdatePart no texture upload needed", + TRACE_EVENT_SCOPE_THREAD); + return false; + } + + bool partial_updates_allowed = + layer_tree_host()->settings().max_partial_texture_updates > 0; + if (!partial_updates_allowed) + resource->texture()->ReturnBackingTexture(); + + gfx::Vector2d dest_offset(0, 0); + resource->Update(queue, rect, dest_offset, partial_updates_allowed); + return true; +} + gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( gfx::Rect layer_rect) const { // Don't intersect with the bounds as in LayerRectToContentRect() because @@ -168,80 +269,85 @@ gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( return expanded_rect; } -gfx::Rect ScrollbarLayer::OriginThumbRect() const { - gfx::Size thumb_size; - if (Orientation() == HORIZONTAL) { - thumb_size = - gfx::Size(scrollbar_->ThumbLength(), scrollbar_->ThumbThickness()); - } else { - thumb_size = - gfx::Size(scrollbar_->ThumbThickness(), scrollbar_->ThumbLength()); +void ScrollbarLayer::SetTexturePriorities( + const PriorityCalculator& priority_calc) { + if (layer_tree_host()->settings().solid_color_scrollbars) + return; + + if (content_bounds().IsEmpty()) + return; + DCHECK_LE(content_bounds().width(), MaxTextureSize()); + DCHECK_LE(content_bounds().height(), MaxTextureSize()); + + CreateUpdaterIfNeeded(); + + bool draws_to_root = !render_target()->parent(); + if (track_) { + track_->texture()->SetDimensions(content_bounds(), texture_format_); + track_->texture()->set_request_priority( + PriorityCalculator::UIPriority(draws_to_root)); + } + if (thumb_) { + gfx::Size thumb_size = OriginThumbRect().size(); + thumb_->texture()->SetDimensions(thumb_size, texture_format_); + thumb_->texture()->set_request_priority( + PriorityCalculator::UIPriority(draws_to_root)); } - return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size)); } bool ScrollbarLayer::Update(ResourceUpdateQueue* queue, const OcclusionTracker* occlusion) { track_rect_ = scrollbar_->TrackRect(); - gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect( - gfx::Rect(scrollbar_->Location(), bounds())); + location_ = scrollbar_->Location(); - if (layer_tree_host()->settings().solid_color_scrollbars || - track_rect_.IsEmpty() || scaled_track_rect.IsEmpty()) + if (layer_tree_host()->settings().solid_color_scrollbars) return false; + bool updated = false; + { base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, true); - ContentsScalingLayer::Update(queue, occlusion); + updated = ContentsScalingLayer::Update(queue, occlusion); } - track_resource_ = ScopedUIResource::Create( - layer_tree_host(), RasterizeScrollbarPart(scaled_track_rect, TRACK)); - gfx::Rect thumb_rect = OriginThumbRect(); + dirty_rect_.Union(update_rect_); + if (content_bounds().IsEmpty()) + return false; + if (visible_content_rect().IsEmpty()) + return false; + + CreateUpdaterIfNeeded(); - if (scrollbar_->HasThumb() && !thumb_rect.IsEmpty()) { + gfx::Rect content_rect = ScrollbarLayerRectToContentRect( + gfx::Rect(scrollbar_->Location(), bounds())); + updated |= UpdatePart(track_updater_.get(), track_.get(), content_rect, + queue); + + if (scrollbar_->HasThumb()) { thumb_thickness_ = scrollbar_->ThumbThickness(); thumb_length_ = scrollbar_->ThumbLength(); - thumb_resource_ = ScopedUIResource::Create( - layer_tree_host(), RasterizeScrollbarPart(thumb_rect, THUMB)); + gfx::Rect origin_thumb_rect = OriginThumbRect(); + if (!origin_thumb_rect.IsEmpty()) { + updated |= UpdatePart(thumb_updater_.get(), thumb_.get(), + origin_thumb_rect, queue); + } } - return true; + dirty_rect_ = gfx::RectF(); + return updated; } -scoped_refptr<UIResourceBitmap> ScrollbarLayer::RasterizeScrollbarPart( - gfx::Rect rect, - ScrollbarPart part) { - DCHECK(!layer_tree_host()->settings().solid_color_scrollbars); - DCHECK(!rect.size().IsEmpty()); - - scoped_refptr<UIResourceBitmap> bitmap = - UIResourceBitmap::Create(new uint8_t[rect.width() * rect.height() * 4], - UIResourceBitmap::RGBA8, - rect.size()); - - SkBitmap skbitmap; - skbitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); - skbitmap.setPixels(bitmap->GetPixels()); - - SkCanvas skcanvas(skbitmap); - skcanvas.translate(SkFloatToScalar(-rect.x()), SkFloatToScalar(-rect.y())); - skcanvas.scale(SkFloatToScalar(contents_scale_x()), - SkFloatToScalar(contents_scale_y())); - - gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( - rect, 1.f / contents_scale_x(), 1.f / contents_scale_y()); - SkRect layer_skrect = RectToSkRect(layer_rect); - SkPaint paint; - paint.setAntiAlias(false); - paint.setXfermodeMode(SkXfermode::kClear_Mode); - skcanvas.drawRect(layer_skrect, paint); - skcanvas.clipRect(layer_skrect); - - scrollbar_->PaintPart(&skcanvas, part, layer_rect); - - return bitmap; +gfx::Rect ScrollbarLayer::OriginThumbRect() const { + gfx::Size thumb_size; + if (Orientation() == HORIZONTAL) { + thumb_size = gfx::Size(scrollbar_->ThumbLength(), + scrollbar_->ThumbThickness()); + } else { + thumb_size = gfx::Size(scrollbar_->ThumbThickness(), + scrollbar_->ThumbLength()); + } + return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size)); } } // namespace cc diff --git a/chromium/cc/layers/scrollbar_layer.h b/chromium/cc/layers/scrollbar_layer.h index a162a7f00f5..6d0e58f7a4e 100644 --- a/chromium/cc/layers/scrollbar_layer.h +++ b/chromium/cc/layers/scrollbar_layer.h @@ -10,9 +10,10 @@ #include "cc/layers/contents_scaling_layer.h" #include "cc/layers/scrollbar_theme_painter.h" #include "cc/resources/layer_updater.h" -#include "cc/resources/scoped_ui_resource.h" namespace cc { +class CachingBitmapContentLayerUpdater; +class ResourceUpdateQueue; class ScrollbarThemeComposite; class CC_EXPORT ScrollbarLayer : public ContentsScalingLayer { @@ -32,6 +33,8 @@ class CC_EXPORT ScrollbarLayer : public ContentsScalingLayer { ScrollbarOrientation Orientation() const; // Layer interface + virtual void SetTexturePriorities(const PriorityCalculator& priority_calc) + OVERRIDE; virtual bool Update(ResourceUpdateQueue* queue, const OcclusionTracker* occlusion) OVERRIDE; virtual void SetLayerTreeHost(LayerTreeHost* host) OVERRIDE; @@ -47,36 +50,42 @@ class CC_EXPORT ScrollbarLayer : public ContentsScalingLayer { virtual ScrollbarLayer* ToScrollbarLayer() OVERRIDE; protected: - ScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id); + ScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, + int scroll_layer_id); virtual ~ScrollbarLayer(); - // For unit tests - UIResourceId track_resource_id() { - return track_resource_.get() ? track_resource_->id() : 0; - } - UIResourceId thumb_resource_id() { - return thumb_resource_.get() ? thumb_resource_->id() : 0; - } - private: + bool UpdatePart(CachingBitmapContentLayerUpdater* painter, + LayerUpdater::Resource* resource, + gfx::Rect rect, + ResourceUpdateQueue* queue); + void CreateUpdaterIfNeeded(); gfx::Rect ScrollbarLayerRectToContentRect(gfx::Rect layer_rect) const; gfx::Rect OriginThumbRect() const; + bool is_dirty() const { return !dirty_rect_.IsEmpty(); } + int MaxTextureSize(); float ClampScaleToMaxTextureSize(float scale); - scoped_refptr<UIResourceBitmap> RasterizeScrollbarPart(gfx::Rect rect, - ScrollbarPart part); - scoped_ptr<Scrollbar> scrollbar_; int thumb_thickness_; int thumb_length_; gfx::Rect track_rect_; + gfx::Point location_; int scroll_layer_id_; - scoped_ptr<ScopedUIResource> track_resource_; - scoped_ptr<ScopedUIResource> thumb_resource_; + unsigned texture_format_; + + gfx::RectF dirty_rect_; + + scoped_refptr<CachingBitmapContentLayerUpdater> track_updater_; + scoped_refptr<CachingBitmapContentLayerUpdater> thumb_updater_; + + // All the parts of the scrollbar except the thumb + scoped_ptr<LayerUpdater::Resource> track_; + scoped_ptr<LayerUpdater::Resource> thumb_; DISALLOW_COPY_AND_ASSIGN(ScrollbarLayer); }; diff --git a/chromium/cc/layers/scrollbar_layer_impl.cc b/chromium/cc/layers/scrollbar_layer_impl.cc index c326d42ff24..1de185a77dd 100644 --- a/chromium/cc/layers/scrollbar_layer_impl.cc +++ b/chromium/cc/layers/scrollbar_layer_impl.cc @@ -31,8 +31,8 @@ ScrollbarLayerImpl::ScrollbarLayerImpl( int id, ScrollbarOrientation orientation) : LayerImpl(tree_impl, id), - track_ui_resource_id_(0), - thumb_ui_resource_id_(0), + track_resource_id_(0), + thumb_resource_id_(0), current_pos_(0.f), maximum_(0), thumb_thickness_(0), @@ -69,8 +69,8 @@ void ScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { scrollbar_layer->SetTrackLength(track_length_); scrollbar_layer->set_is_overlay_scrollbar(is_overlay_scrollbar_); - scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_); - scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_); + scrollbar_layer->set_track_resource_id(track_resource_id_); + scrollbar_layer->set_thumb_resource_id(thumb_resource_id_); } bool ScrollbarLayerImpl::WillDraw(DrawMode draw_mode, @@ -106,19 +106,14 @@ void ScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink, return; } - ResourceProvider::ResourceId thumb_resource_id = - layer_tree_impl()->ResourceIdForUIResource(thumb_ui_resource_id_); - ResourceProvider::ResourceId track_resource_id = - layer_tree_impl()->ResourceIdForUIResource(track_ui_resource_id_); - - if (thumb_resource_id && !thumb_quad_rect.IsEmpty()) { + if (thumb_resource_id_ && !thumb_quad_rect.IsEmpty()) { gfx::Rect opaque_rect; const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); quad->SetNew(shared_quad_state, thumb_quad_rect, opaque_rect, - thumb_resource_id, + thumb_resource_id_, premultipled_alpha, uv_top_left, uv_bottom_right, @@ -128,15 +123,21 @@ void ScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink, quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); } - gfx::Rect track_quad_rect = content_bounds_rect; - if (track_resource_id && !track_quad_rect.IsEmpty()) { - gfx::Rect opaque_rect(contents_opaque() ? track_quad_rect : gfx::Rect()); + if (!track_resource_id_) + return; + + // Order matters here: since the back track texture is being drawn to the + // entire contents rect, we must append it after the thumb and fore track + // quads. The back track texture contains (and displays) the buttons. + if (!content_bounds_rect.IsEmpty()) { + gfx::Rect quad_rect(content_bounds_rect); + gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect()); const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); quad->SetNew(shared_quad_state, - track_quad_rect, + quad_rect, opaque_rect, - track_resource_id, + track_resource_id_, premultipled_alpha, uv_top_left, uv_bottom_right, @@ -315,6 +316,11 @@ gfx::Rect ScrollbarLayerImpl::ComputeThumbQuadRect() const { return ScrollbarLayerRectToContentRect(thumb_rect); } +void ScrollbarLayerImpl::DidLoseOutputSurface() { + track_resource_id_ = 0; + thumb_resource_id_ = 0; +} + const char* ScrollbarLayerImpl::LayerTypeAsString() const { return "cc::ScrollbarLayerImpl"; } diff --git a/chromium/cc/layers/scrollbar_layer_impl.h b/chromium/cc/layers/scrollbar_layer_impl.h index 86bf25558a0..6347c413dfc 100644 --- a/chromium/cc/layers/scrollbar_layer_impl.h +++ b/chromium/cc/layers/scrollbar_layer_impl.h @@ -8,7 +8,6 @@ #include "cc/base/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/layer_impl.h" -#include "cc/resources/ui_resource_client.h" namespace cc { @@ -34,6 +33,8 @@ class CC_EXPORT ScrollbarLayerImpl : public LayerImpl { virtual void AppendQuads(QuadSink* quad_sink, AppendQuadsData* append_quads_data) OVERRIDE; + virtual void DidLoseOutputSurface() OVERRIDE; + int scroll_layer_id() const { return scroll_layer_id_; } void set_scroll_layer_id(int id) { scroll_layer_id_ = id; } @@ -47,11 +48,11 @@ class CC_EXPORT ScrollbarLayerImpl : public LayerImpl { void SetTrackStart(int track_start); void SetTrackLength(int track_length); void SetVerticalAdjust(float vertical_adjust); - void set_track_ui_resource_id(UIResourceId uid) { - track_ui_resource_id_ = uid; + void set_track_resource_id(ResourceProvider::ResourceId id) { + track_resource_id_ = id; } - void set_thumb_ui_resource_id(UIResourceId uid) { - thumb_ui_resource_id_ = uid; + void set_thumb_resource_id(ResourceProvider::ResourceId id) { + thumb_resource_id_ = id; } void SetVisibleToTotalLengthRatio(float ratio); void set_is_overlay_scrollbar(bool is_overlay_scrollbar) { @@ -74,8 +75,8 @@ class CC_EXPORT ScrollbarLayerImpl : public LayerImpl { gfx::Rect ScrollbarLayerRectToContentRect(gfx::RectF layer_rect) const; - UIResourceId track_ui_resource_id_; - UIResourceId thumb_ui_resource_id_; + ResourceProvider::ResourceId track_resource_id_; + ResourceProvider::ResourceId thumb_resource_id_; float current_pos_; int maximum_; diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc index 79cfbb1f26d..b7981041f09 100644 --- a/chromium/cc/layers/scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/scrollbar_layer_unittest.cc @@ -4,23 +4,22 @@ #include "cc/layers/scrollbar_layer.h" -#include "base/containers/hash_tables.h" #include "cc/animation/scrollbar_animation_controller.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/scrollbar_layer_impl.h" #include "cc/quads/solid_color_draw_quad.h" +#include "cc/resources/prioritized_resource_manager.h" +#include "cc/resources/priority_calculator.h" #include "cc/resources/resource_update_queue.h" #include "cc/test/fake_impl_proxy.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_scrollbar.h" -#include "cc/test/fake_scrollbar_layer.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_tree_test.h" #include "cc/test/mock_quad_culler.h" -#include "cc/trees/layer_tree_host.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/tree_synchronizer.h" @@ -405,48 +404,9 @@ class MockLayerTreeHost : public LayerTreeHost { public: MockLayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings) - : LayerTreeHost(client, settings), - next_id_(1), - total_ui_resource_created_(0), - total_ui_resource_deleted_(0) { + : LayerTreeHost(client, settings) { Initialize(NULL); } - - virtual UIResourceId CreateUIResource(UIResourceClient* content) OVERRIDE { - total_ui_resource_created_++; - UIResourceId nid = next_id_++; - ui_resource_bitmap_map_[nid] = content->GetBitmap(nid, false); - return nid; - } - - // Deletes a UI resource. May safely be called more than once. - virtual void DeleteUIResource(UIResourceId id) OVERRIDE { - UIResourceBitmapMap::iterator iter = ui_resource_bitmap_map_.find(id); - if (iter != ui_resource_bitmap_map_.end()) { - ui_resource_bitmap_map_.erase(iter); - total_ui_resource_deleted_++; - } - } - - size_t UIResourceCount() { return ui_resource_bitmap_map_.size(); } - int TotalUIResourceDeleted() { return total_ui_resource_deleted_; } - int TotalUIResourceCreated() { return total_ui_resource_created_; } - - gfx::Size ui_resource_size(UIResourceId id) { - UIResourceBitmapMap::iterator iter = ui_resource_bitmap_map_.find(id); - if (iter != ui_resource_bitmap_map_.end() && iter->second.get()) - return iter->second->GetSize(); - return gfx::Size(); - } - - private: - typedef base::hash_map<UIResourceId, scoped_refptr<UIResourceBitmap> > - UIResourceBitmapMap; - UIResourceBitmapMap ui_resource_bitmap_map_; - - int next_id_; - int total_ui_resource_created_; - int total_ui_resource_deleted_; }; @@ -455,10 +415,7 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { ScrollbarLayerTestResourceCreation() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} - void TestResourceUpload(int num_updates, - size_t expected_resources, - int expected_created, - int expected_deleted) { + void TestResourceUpload(size_t expected_resources) { layer_tree_host_.reset( new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); @@ -466,11 +423,13 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<Layer> scrollbar_layer = - ScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); + ScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); layer_tree_host_->InitializeOutputSurfaceIfNeeded(); + layer_tree_host_->contents_texture_manager()-> + SetMaxMemoryLimitBytes(1024 * 1024); layer_tree_host_->SetRootLayer(layer_tree_root); scrollbar_layer->SetIsDrawable(true); @@ -488,17 +447,16 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); + PriorityCalculator calculator; ResourceUpdateQueue queue; OcclusionTracker occlusion_tracker(gfx::Rect(), false); scrollbar_layer->SavePaintProperties(); - for (int update_counter = 0; update_counter < num_updates; update_counter++) - scrollbar_layer->Update(&queue, &occlusion_tracker); - - // A non-solid-color scrollbar should have requested two textures. - EXPECT_EQ(expected_resources, layer_tree_host_->UIResourceCount()); - EXPECT_EQ(expected_created, layer_tree_host_->TotalUIResourceCreated()); - EXPECT_EQ(expected_deleted, layer_tree_host_->TotalUIResourceDeleted()); + scrollbar_layer->SetTexturePriorities(calculator); + layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); + scrollbar_layer->Update(&queue, &occlusion_tracker); + EXPECT_EQ(0u, queue.FullUploadSize()); + EXPECT_EQ(expected_resources, queue.PartialUploadSize()); testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); @@ -513,18 +471,12 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { TEST_F(ScrollbarLayerTestResourceCreation, ResourceUpload) { layer_tree_settings_.solid_color_scrollbars = false; - TestResourceUpload(0, 0, 0, 0); - int num_updates[3] = {1, 5, 10}; - for (int j = 0; j < 3; j++) { - TestResourceUpload( - num_updates[j], 2, num_updates[j] * 2, (num_updates[j] - 1) * 2); - } + TestResourceUpload(2); } TEST_F(ScrollbarLayerTestResourceCreation, SolidColorNoResourceUpload) { layer_tree_settings_.solid_color_scrollbars = true; - TestResourceUpload(0, 0, 0, 0); - TestResourceUpload(1, 0, 0, 0); + TestResourceUpload(0); } class ScaledScrollbarLayerTestResourceCreation : public testing::Test { @@ -532,20 +484,25 @@ class ScaledScrollbarLayerTestResourceCreation : public testing::Test { ScaledScrollbarLayerTestResourceCreation() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} - void TestResourceUpload(const float test_scale) { + void TestResourceUpload(size_t expected_resources, const float test_scale) { layer_tree_host_.reset( new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); gfx::Point scrollbar_location(0, 185); + scoped_ptr<FakeScrollbar> scrollbar(new FakeScrollbar(false, true, false)); + scrollbar->set_location(scrollbar_location); + scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); - scoped_refptr<FakeScrollbarLayer> scrollbar_layer = - FakeScrollbarLayer::Create(false, true, layer_tree_root->id()); - + scoped_refptr<Layer> scrollbar_layer = + ScrollbarLayer::Create(scrollbar.PassAs<cc::Scrollbar>(), + layer_tree_root->id()); layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); layer_tree_host_->InitializeOutputSurfaceIfNeeded(); + layer_tree_host_->contents_texture_manager()-> + SetMaxMemoryLimitBytes(1024 * 1024); layer_tree_host_->SetRootLayer(layer_tree_root); scrollbar_layer->SetIsDrawable(true); @@ -572,23 +529,30 @@ class ScaledScrollbarLayerTestResourceCreation : public testing::Test { testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); + PriorityCalculator calculator; ResourceUpdateQueue queue; OcclusionTracker occlusion_tracker(gfx::Rect(), false); + scrollbar_layer->SavePaintProperties(); + scrollbar_layer->SetTexturePriorities(calculator); + layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); scrollbar_layer->Update(&queue, &occlusion_tracker); + EXPECT_EQ(expected_resources, queue.PartialUploadSize()); // Verify that we have not generated any content uploads that are larger // than their destination textures. - - gfx::Size track_size = layer_tree_host_->ui_resource_size( - scrollbar_layer->track_resource_id()); - gfx::Size thumb_size = layer_tree_host_->ui_resource_size( - scrollbar_layer->thumb_resource_id()); - - EXPECT_LE(track_size.width(), scrollbar_layer->content_bounds().width()); - EXPECT_LE(track_size.height(), scrollbar_layer->content_bounds().height()); - EXPECT_LE(thumb_size.width(), scrollbar_layer->content_bounds().width()); - EXPECT_LE(thumb_size.height(), scrollbar_layer->content_bounds().height()); + while (queue.HasMoreUpdates()) { + ResourceUpdate update = queue.TakeFirstPartialUpload(); + EXPECT_LE(update.texture->size().width(), + scrollbar_layer->content_bounds().width()); + EXPECT_LE(update.texture->size().height(), + scrollbar_layer->content_bounds().height()); + + EXPECT_LE(update.dest_offset.x() + update.content_rect.width(), + update.texture->size().width()); + EXPECT_LE(update.dest_offset.y() + update.content_rect.height(), + update.texture->size().height()); + } testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); @@ -605,9 +569,7 @@ TEST_F(ScaledScrollbarLayerTestResourceCreation, ScaledResourceUpload) { layer_tree_settings_.solid_color_scrollbars = false; // Pick a test scale that moves the scrollbar's (non-zero) position to // a non-pixel-aligned location. - TestResourceUpload(.041f); - TestResourceUpload(1.41f); - TestResourceUpload(4.1f); + TestResourceUpload(2, 1.41f); } } // namespace diff --git a/chromium/cc/layers/texture_layer.cc b/chromium/cc/layers/texture_layer.cc index 2325a80c793..11009fa1b68 100644 --- a/chromium/cc/layers/texture_layer.cc +++ b/chromium/cc/layers/texture_layer.cc @@ -196,6 +196,7 @@ bool TextureLayer::Update(ResourceUpdateQueue* queue, client_->Context3d()->getGraphicsResetStatusARB() != GL_NO_ERROR) texture_id_ = 0; updated = true; + SetNeedsPushProperties(); } } diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc index 744bf004956..aa08e9f81ee 100644 --- a/chromium/cc/layers/texture_layer_unittest.cc +++ b/chromium/cc/layers/texture_layer_unittest.cc @@ -7,13 +7,11 @@ #include <string> #include "base/callback.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/layers/texture_layer_client.h" #include "cc/layers/texture_layer_impl.h" #include "cc/test/fake_impl_proxy.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_layer_tree_host_impl.h" -#include "cc/test/fake_output_surface.h" #include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/trees/layer_tree_host.h" diff --git a/chromium/cc/output/gl_renderer.cc b/chromium/cc/output/gl_renderer.cc index 61d0eaaafc4..2dc699104ab 100644 --- a/chromium/cc/output/gl_renderer.cc +++ b/chromium/cc/output/gl_renderer.cc @@ -2348,7 +2348,7 @@ void GLRenderer::DoGetFramebufferPixels( if (is_async) { query = context_->createQueryEXT(); GLC(context_, context_->beginQueryEXT( - GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, + GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM, query)); } @@ -2389,7 +2389,7 @@ void GLRenderer::DoGetFramebufferPixels( if (is_async) { GLC(context_, context_->endQueryEXT( - GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM)); + GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM)); SyncPointHelper::SignalQuery( context_, query, diff --git a/chromium/cc/output/gl_renderer_unittest.cc b/chromium/cc/output/gl_renderer_unittest.cc index 9e930ccd023..e4213d65842 100644 --- a/chromium/cc/output/gl_renderer_unittest.cc +++ b/chromium/cc/output/gl_renderer_unittest.cc @@ -7,7 +7,6 @@ #include <set> #include "cc/base/math_util.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/resources/prioritized_resource_manager.h" #include "cc/resources/resource_provider.h" @@ -19,6 +18,7 @@ #include "cc/test/pixel_test.h" #include "cc/test/render_pass_test_common.h" #include "cc/test/render_pass_test_utils.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/cc/output/output_surface.cc b/chromium/cc/output/output_surface.cc index 5d2c6bb6e9f..be990cc0cb7 100644 --- a/chromium/cc/output/output_surface.cc +++ b/chromium/cc/output/output_surface.cc @@ -219,7 +219,7 @@ void OutputSurface::BeginFrame(const BeginFrameArgs& args) { } } -base::TimeDelta OutputSurface::AlternateRetroactiveBeginFramePeriod() { +base::TimeDelta OutputSurface::RetroactiveBeginFramePeriod() { return BeginFrameArgs::DefaultRetroactiveBeginFramePeriod(); } @@ -239,11 +239,9 @@ void OutputSurface::CheckForRetroactiveBeginFrame() { TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame"); check_for_retroactive_begin_frame_pending_ = false; base::TimeTicks now = base::TimeTicks::Now(); - // TODO(brianderson): Remove the alternative deadline once we have better - // deadline estimations. base::TimeTicks alternative_deadline = skipped_begin_frame_args_.frame_time + - AlternateRetroactiveBeginFramePeriod(); + RetroactiveBeginFramePeriod(); if (now < skipped_begin_frame_args_.deadline || now < alternative_deadline) { BeginFrame(skipped_begin_frame_args_); diff --git a/chromium/cc/output/output_surface.h b/chromium/cc/output/output_surface.h index 73f1c750851..86d4dc81dd3 100644 --- a/chromium/cc/output/output_surface.h +++ b/chromium/cc/output/output_surface.h @@ -174,7 +174,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { gfx::Rect viewport); // virtual for testing. - virtual base::TimeDelta AlternateRetroactiveBeginFramePeriod(); + virtual base::TimeDelta RetroactiveBeginFramePeriod(); virtual void PostCheckForRetroactiveBeginFrame(); void CheckForRetroactiveBeginFrame(); diff --git a/chromium/cc/output/output_surface_unittest.cc b/chromium/cc/output/output_surface_unittest.cc index 4f9e370e1f0..276828c04aa 100644 --- a/chromium/cc/output/output_surface_unittest.cc +++ b/chromium/cc/output/output_surface_unittest.cc @@ -5,13 +5,13 @@ #include "cc/output/output_surface.h" #include "base/test/test_simple_task_runner.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface_client.h" #include "cc/output/software_output_device.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" #include "cc/test/scheduler_test_common.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebGraphicsMemoryAllocation.h" @@ -67,8 +67,8 @@ class TestOutputSurface : public OutputSurface { OnSwapBuffersComplete(NULL); } - void SetAlternateRetroactiveBeginFramePeriod(base::TimeDelta period) { - alternate_retroactive_begin_frame_period_ = period; + void SetRetroactiveBeginFramePeriod(base::TimeDelta period) { + retroactive_begin_frame_period_ = period; } protected: @@ -77,11 +77,11 @@ class TestOutputSurface : public OutputSurface { CheckForRetroactiveBeginFrame(); } - virtual base::TimeDelta AlternateRetroactiveBeginFramePeriod() OVERRIDE { - return alternate_retroactive_begin_frame_period_; + virtual base::TimeDelta RetroactiveBeginFramePeriod() OVERRIDE { + return retroactive_begin_frame_period_; } - base::TimeDelta alternate_retroactive_begin_frame_period_; + base::TimeDelta retroactive_begin_frame_period_; }; TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientSuccess) { @@ -202,7 +202,7 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { display_refresh_interval); output_surface.SetMaxFramesPending(2); - output_surface.SetAlternateRetroactiveBeginFramePeriod( + output_surface.SetRetroactiveBeginFramePeriod( base::TimeDelta::FromSeconds(-1)); // We should start off with 0 BeginFrames @@ -279,7 +279,7 @@ TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) { output_surface.SetMaxFramesPending(2); // Enable retroactive BeginFrames. - output_surface.SetAlternateRetroactiveBeginFramePeriod( + output_surface.SetRetroactiveBeginFramePeriod( base::TimeDelta::FromSeconds(100000)); // Optimistically injected BeginFrames should be throttled if @@ -317,63 +317,6 @@ TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) { EXPECT_EQ(client.begin_frame_count(), 4); } -TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) { - scoped_ptr<TestWebGraphicsContext3D> context3d = - TestWebGraphicsContext3D::Create(); - - TestOutputSurface output_surface( - context3d.PassAs<WebKit::WebGraphicsContext3D>()); - EXPECT_FALSE(output_surface.HasClientForTesting()); - - FakeOutputSurfaceClient client; - EXPECT_TRUE(output_surface.BindToClient(&client)); - EXPECT_TRUE(output_surface.HasClientForTesting()); - EXPECT_FALSE(client.deferred_initialize_called()); - - base::TimeDelta big_interval = base::TimeDelta::FromSeconds(1000); - - // Initialize BeginFrame emulation - scoped_refptr<base::TestSimpleTaskRunner> task_runner = - new base::TestSimpleTaskRunner; - bool throttle_frame_production = true; - const base::TimeDelta display_refresh_interval = big_interval; - - output_surface.InitializeBeginFrameEmulation( - task_runner.get(), - throttle_frame_production, - display_refresh_interval); - - // We need to subtract an epsilon from Now() because some platforms have - // a slow clock. - output_surface.OnVSyncParametersChangedForTesting( - base::TimeTicks::Now() - base::TimeDelta::FromMilliseconds(1), - display_refresh_interval); - - output_surface.SetMaxFramesPending(2); - output_surface.SetAlternateRetroactiveBeginFramePeriod( - base::TimeDelta::FromSeconds(-1)); - - // We should start off with 0 BeginFrames - EXPECT_EQ(client.begin_frame_count(), 0); - EXPECT_EQ(output_surface.pending_swap_buffers(), 0); - - // The first SetNeedsBeginFrame(true) should start a retroactive BeginFrame. - output_surface.SetNeedsBeginFrame(true); - EXPECT_TRUE(task_runner->HasPendingTask()); - EXPECT_GT(task_runner->NextPendingTaskDelay(), big_interval / 2); - EXPECT_EQ(client.begin_frame_count(), 1); - - output_surface.SetNeedsBeginFrame(false); - EXPECT_TRUE(task_runner->HasPendingTask()); - EXPECT_EQ(client.begin_frame_count(), 1); - - // The second SetNeedBeginFrame(true) should not retroactively start a - // BeginFrame if the timestamp would be the same as the previous BeginFrame. - output_surface.SetNeedsBeginFrame(true); - EXPECT_TRUE(task_runner->HasPendingTask()); - EXPECT_EQ(client.begin_frame_count(), 1); -} - TEST(OutputSurfaceTest, MemoryAllocation) { scoped_ptr<TestWebGraphicsContext3D> scoped_context = TestWebGraphicsContext3D::Create(); diff --git a/chromium/cc/output/software_renderer.cc b/chromium/cc/output/software_renderer.cc index 7735e3c8c10..9bf2efef39f 100644 --- a/chromium/cc/output/software_renderer.cc +++ b/chromium/cc/output/software_renderer.cc @@ -19,6 +19,7 @@ #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/texture_draw_quad.h" #include "cc/quads/tile_draw_quad.h" +#include "skia/ext/opacity_draw_filter.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkDevice.h" @@ -310,27 +311,20 @@ void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame, SkMatrix::kFill_ScaleToFit); current_canvas_->concat(content_matrix); - if (quad->ShouldDrawWithBlending()) { - TRACE_EVENT0("cc", "SoftwareRenderer::DrawPictureQuad with blending"); - SkBitmap temp_bitmap; - temp_bitmap.setConfig(SkBitmap::kARGB_8888_Config, - quad->texture_size.width(), - quad->texture_size.height()); - temp_bitmap.allocPixels(); - SkDevice temp_device(temp_bitmap); - SkCanvas temp_canvas(&temp_device); - - quad->picture_pile->RasterToBitmap( - &temp_canvas, quad->content_rect, quad->contents_scale, NULL); + // TODO(aelias): This isn't correct in all cases. We should detect these + // cases and fall back to a persistent bitmap backing + // (http://crbug.com/280374). + skia::RefPtr<SkDrawFilter> opacity_filter = + skia::AdoptRef(new skia::OpacityDrawFilter(quad->opacity(), true)); + DCHECK(!current_canvas_->getDrawFilter()); + current_canvas_->setDrawFilter(opacity_filter.get()); - current_paint_.setFilterBitmap(true); - current_canvas_->drawBitmap(temp_bitmap, 0, 0, ¤t_paint_); - } else { - TRACE_EVENT0("cc", - "SoftwareRenderer::DrawPictureQuad direct from PicturePile"); - quad->picture_pile->RasterDirect( - current_canvas_, quad->content_rect, quad->contents_scale, NULL); - } + TRACE_EVENT0("cc", + "SoftwareRenderer::DrawPictureQuad"); + quad->picture_pile->RasterDirect( + current_canvas_, quad->content_rect, quad->contents_scale, NULL); + + current_canvas_->setDrawFilter(NULL); } void SoftwareRenderer::DrawSolidColorQuad(const DrawingFrame* frame, diff --git a/chromium/cc/resources/prioritized_tile_set.cc b/chromium/cc/resources/prioritized_tile_set.cc index 6255be94137..5b40945e559 100644 --- a/chromium/cc/resources/prioritized_tile_set.cc +++ b/chromium/cc/resources/prioritized_tile_set.cc @@ -67,52 +67,37 @@ void SortBinTiles(ManagedTileBin bin, TileVector* tiles) { } // namespace -PrioritizedTileSet::PrioritizedTileSet() { - for (int bin = 0; bin < NUM_BINS; ++bin) - bin_sorted_[bin] = true; -} +PrioritizedTileSet::PrioritizedTileSet() {} PrioritizedTileSet::~PrioritizedTileSet() {} void PrioritizedTileSet::InsertTile(Tile* tile, ManagedTileBin bin) { tiles_[bin].push_back(make_scoped_refptr(tile)); - bin_sorted_[bin] = false; } void PrioritizedTileSet::Clear() { - for (int bin = 0; bin < NUM_BINS; ++bin) { + for (int bin = 0; bin < NUM_BINS; ++bin) tiles_[bin].clear(); - bin_sorted_[bin] = true; - } } -void PrioritizedTileSet::SortBinIfNeeded(ManagedTileBin bin) { - if (!bin_sorted_[bin]) { - SortBinTiles(bin, &tiles_[bin]); - bin_sorted_[bin] = true; - } +void PrioritizedTileSet::Sort() { + for (int bin = 0; bin < NUM_BINS; ++bin) + SortBinTiles(static_cast<ManagedTileBin>(bin), &tiles_[bin]); } -PrioritizedTileSet::Iterator::Iterator( - PrioritizedTileSet* tile_set, bool use_priority_ordering) +PrioritizedTileSet::PriorityIterator::PriorityIterator( + PrioritizedTileSet* tile_set) : tile_set_(tile_set), current_bin_(NOW_AND_READY_TO_DRAW_BIN), - use_priority_ordering_(use_priority_ordering) { - if (use_priority_ordering_) - tile_set_->SortBinIfNeeded(current_bin_); - iterator_ = tile_set->tiles_[current_bin_].begin(); + iterator_(tile_set->tiles_[current_bin_].begin()) { if (iterator_ == tile_set_->tiles_[current_bin_].end()) AdvanceList(); } -PrioritizedTileSet::Iterator::~Iterator() {} - -void PrioritizedTileSet::Iterator::DisablePriorityOrdering() { - use_priority_ordering_ = false; -} +PrioritizedTileSet::PriorityIterator::~PriorityIterator() {} -PrioritizedTileSet::Iterator& -PrioritizedTileSet::Iterator::operator++() { +PrioritizedTileSet::PriorityIterator& +PrioritizedTileSet::PriorityIterator::operator++() { // We can't increment past the end of the tiles. DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end()); @@ -122,20 +107,16 @@ PrioritizedTileSet::Iterator::operator++() { return *this; } -Tile* PrioritizedTileSet::Iterator::operator*() { +Tile* PrioritizedTileSet::PriorityIterator::operator*() { DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end()); return iterator_->get(); } -void PrioritizedTileSet::Iterator::AdvanceList() { +void PrioritizedTileSet::PriorityIterator::AdvanceList() { DCHECK(iterator_ == tile_set_->tiles_[current_bin_].end()); while (current_bin_ != NEVER_BIN) { current_bin_ = static_cast<ManagedTileBin>(current_bin_ + 1); - - if (use_priority_ordering_) - tile_set_->SortBinIfNeeded(current_bin_); - iterator_ = tile_set_->tiles_[current_bin_].begin(); if (iterator_ != tile_set_->tiles_[current_bin_].end()) break; diff --git a/chromium/cc/resources/prioritized_tile_set.h b/chromium/cc/resources/prioritized_tile_set.h index 366179b05c8..fe1b2a0a941 100644 --- a/chromium/cc/resources/prioritized_tile_set.h +++ b/chromium/cc/resources/prioritized_tile_set.h @@ -22,16 +22,14 @@ class CC_EXPORT PrioritizedTileSet { void InsertTile(Tile* tile, ManagedTileBin bin); void Clear(); + void Sort(); - class CC_EXPORT Iterator { + class CC_EXPORT PriorityIterator { public: - Iterator(PrioritizedTileSet* set, bool use_priority_ordering); + explicit PriorityIterator(PrioritizedTileSet* set); + ~PriorityIterator(); - ~Iterator(); - - void DisablePriorityOrdering(); - - Iterator& operator++(); + PriorityIterator& operator++(); Tile* operator->() { return *(*this); } Tile* operator*(); operator bool() const { @@ -44,17 +42,13 @@ class CC_EXPORT PrioritizedTileSet { PrioritizedTileSet* tile_set_; ManagedTileBin current_bin_; std::vector<scoped_refptr<Tile> >::iterator iterator_; - bool use_priority_ordering_; }; private: - friend class Iterator; - - void SortBinIfNeeded(ManagedTileBin bin); + friend class PriorityIterator; typedef scoped_refptr<Tile> TileRef; std::vector<TileRef> tiles_[NUM_BINS]; - bool bin_sorted_[NUM_BINS]; }; } // namespace cc diff --git a/chromium/cc/resources/prioritized_tile_set_unittest.cc b/chromium/cc/resources/prioritized_tile_set_unittest.cc index e244aefdbb9..645fa04d497 100644 --- a/chromium/cc/resources/prioritized_tile_set_unittest.cc +++ b/chromium/cc/resources/prioritized_tile_set_unittest.cc @@ -83,12 +83,10 @@ class PrioritizedTileSetTest : public testing::Test { }; TEST_F(PrioritizedTileSetTest, EmptyIterator) { - // Creating an iterator to an empty set should work (but create iterator that - // isn't valid). - PrioritizedTileSet set; + set.Sort(); - PrioritizedTileSet::Iterator it(&set, true); + PrioritizedTileSet::PriorityIterator it(&set); EXPECT_FALSE(it); } @@ -96,8 +94,9 @@ TEST_F(PrioritizedTileSetTest, NonEmptyIterator) { PrioritizedTileSet set; scoped_refptr<Tile> tile = CreateTile(); set.InsertTile(tile, NOW_BIN); + set.Sort(); - PrioritizedTileSet::Iterator it(&set, true); + PrioritizedTileSet::PriorityIterator it(&set); EXPECT_TRUE(it); EXPECT_TRUE(*it == tile.get()); ++it; @@ -105,8 +104,6 @@ TEST_F(PrioritizedTileSetTest, NonEmptyIterator) { } TEST_F(PrioritizedTileSetTest, NowAndReadyToDrawBin) { - // Ensure that tiles in NOW_AND_READY_TO_DRAW_BIN aren't sorted. - PrioritizedTileSet set; TilePriority priorities[4] = { TilePriorityForEventualBin(), @@ -125,9 +122,11 @@ TEST_F(PrioritizedTileSetTest, NowAndReadyToDrawBin) { } } + set.Sort(); + // Tiles should appear in the same order as inserted. int i = 0; - for (PrioritizedTileSet::Iterator it(&set, true); + for (PrioritizedTileSet::PriorityIterator it(&set); it; ++it) { EXPECT_TRUE(*it == tiles[i].get()); @@ -137,8 +136,6 @@ TEST_F(PrioritizedTileSetTest, NowAndReadyToDrawBin) { } TEST_F(PrioritizedTileSetTest, NowBin) { - // Ensure that tiles in NOW_BIN are sorted according to BinComparator. - PrioritizedTileSet set; TilePriority priorities[4] = { TilePriorityForEventualBin(), @@ -157,11 +154,13 @@ TEST_F(PrioritizedTileSetTest, NowBin) { } } + set.Sort(); + // Tiles should appear in BinComparator order. std::sort(tiles.begin(), tiles.end(), BinComparator()); int i = 0; - for (PrioritizedTileSet::Iterator it(&set, true); + for (PrioritizedTileSet::PriorityIterator it(&set); it; ++it) { EXPECT_TRUE(*it == tiles[i].get()); @@ -171,8 +170,6 @@ TEST_F(PrioritizedTileSetTest, NowBin) { } TEST_F(PrioritizedTileSetTest, SoonBin) { - // Ensure that tiles in SOON_BIN are sorted according to BinComparator. - PrioritizedTileSet set; TilePriority priorities[4] = { TilePriorityForEventualBin(), @@ -191,43 +188,13 @@ TEST_F(PrioritizedTileSetTest, SoonBin) { } } + set.Sort(); + // Tiles should appear in BinComparator order. std::sort(tiles.begin(), tiles.end(), BinComparator()); int i = 0; - for (PrioritizedTileSet::Iterator it(&set, true); - it; - ++it) { - EXPECT_TRUE(*it == tiles[i].get()); - ++i; - } - EXPECT_EQ(20, i); -} - -TEST_F(PrioritizedTileSetTest, SoonBinNoPriority) { - // Ensure that when not using priority iterator, SOON_BIN tiles - // are not sorted. - - PrioritizedTileSet set; - TilePriority priorities[4] = { - TilePriorityForEventualBin(), - TilePriorityForNowBin(), - TilePriority(), - TilePriorityForSoonBin()}; - - std::vector<scoped_refptr<Tile> > tiles; - for (int priority = 0; priority < 4; ++priority) { - for (int i = 0; i < 5; ++i) { - scoped_refptr<Tile> tile = CreateTile(); - tile->SetPriority(ACTIVE_TREE, priorities[priority]); - tile->SetPriority(PENDING_TREE, priorities[priority]); - tiles.push_back(tile); - set.InsertTile(tile, SOON_BIN); - } - } - - int i = 0; - for (PrioritizedTileSet::Iterator it(&set, false); + for (PrioritizedTileSet::PriorityIterator it(&set); it; ++it) { EXPECT_TRUE(*it == tiles[i].get()); @@ -237,8 +204,6 @@ TEST_F(PrioritizedTileSetTest, SoonBinNoPriority) { } TEST_F(PrioritizedTileSetTest, EventuallyAndActiveBin) { - // Ensure that EVENTUALLY_AND_ACTIVE_BIN tiles are sorted. - PrioritizedTileSet set; TilePriority priorities[4] = { TilePriorityForEventualBin(), @@ -257,11 +222,13 @@ TEST_F(PrioritizedTileSetTest, EventuallyAndActiveBin) { } } + set.Sort(); + // Tiles should appear in BinComparator order. std::sort(tiles.begin(), tiles.end(), BinComparator()); int i = 0; - for (PrioritizedTileSet::Iterator it(&set, true); + for (PrioritizedTileSet::PriorityIterator it(&set); it; ++it) { EXPECT_TRUE(*it == tiles[i].get()); @@ -271,8 +238,6 @@ TEST_F(PrioritizedTileSetTest, EventuallyAndActiveBin) { } TEST_F(PrioritizedTileSetTest, EventuallyBin) { - // Ensure that EVENTUALLY_BIN tiles are sorted. - PrioritizedTileSet set; TilePriority priorities[4] = { TilePriorityForEventualBin(), @@ -291,11 +256,13 @@ TEST_F(PrioritizedTileSetTest, EventuallyBin) { } } + set.Sort(); + // Tiles should appear in BinComparator order. std::sort(tiles.begin(), tiles.end(), BinComparator()); int i = 0; - for (PrioritizedTileSet::Iterator it(&set, true); + for (PrioritizedTileSet::PriorityIterator it(&set); it; ++it) { EXPECT_TRUE(*it == tiles[i].get()); @@ -305,8 +272,6 @@ TEST_F(PrioritizedTileSetTest, EventuallyBin) { } TEST_F(PrioritizedTileSetTest, NeverAndActiveBin) { - // Ensure that NEVER_AND_ACTIVE_BIN tiles are sorted. - PrioritizedTileSet set; TilePriority priorities[4] = { TilePriorityForEventualBin(), @@ -325,11 +290,13 @@ TEST_F(PrioritizedTileSetTest, NeverAndActiveBin) { } } + set.Sort(); + // Tiles should appear in BinComparator order. std::sort(tiles.begin(), tiles.end(), BinComparator()); int i = 0; - for (PrioritizedTileSet::Iterator it(&set, true); + for (PrioritizedTileSet::PriorityIterator it(&set); it; ++it) { EXPECT_TRUE(*it == tiles[i].get()); @@ -339,9 +306,6 @@ TEST_F(PrioritizedTileSetTest, NeverAndActiveBin) { } TEST_F(PrioritizedTileSetTest, NeverBin) { - // Ensure that NEVER_BIN tiles are sorted, since they might not - // be NEVER_BIN on a LOW_PRIORITY tree. - PrioritizedTileSet set; TilePriority priorities[4] = { TilePriorityForEventualBin(), @@ -360,11 +324,13 @@ TEST_F(PrioritizedTileSetTest, NeverBin) { } } + set.Sort(); + // Tiles should appear in BinComparator order. std::sort(tiles.begin(), tiles.end(), BinComparator()); int i = 0; - for (PrioritizedTileSet::Iterator it(&set, true); + for (PrioritizedTileSet::PriorityIterator it(&set); it; ++it) { EXPECT_TRUE(*it == tiles[i].get()); @@ -374,9 +340,6 @@ TEST_F(PrioritizedTileSetTest, NeverBin) { } TEST_F(PrioritizedTileSetTest, TilesForEachBin) { - // Aggregate test with one tile for each of the bins, which - // should appear in order of the bins. - scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile(); scoped_refptr<Tile> now_bin = CreateTile(); scoped_refptr<Tile> soon_bin = CreateTile(); @@ -394,8 +357,10 @@ TEST_F(PrioritizedTileSetTest, TilesForEachBin) { set.InsertTile(never_bin, NEVER_BIN); set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN); + set.Sort(); + // Tiles should appear in order. - PrioritizedTileSet::Iterator it(&set, true); + PrioritizedTileSet::PriorityIterator it(&set); EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get()); ++it; EXPECT_TRUE(*it == now_bin.get()); @@ -413,229 +378,7 @@ TEST_F(PrioritizedTileSetTest, TilesForEachBin) { EXPECT_FALSE(it); } -TEST_F(PrioritizedTileSetTest, ManyTilesForEachBin) { - // Aggregate test with many tiles in each of the bins of various - // priorities. Ensure that they are all returned in a sorted order. - - std::vector<scoped_refptr<Tile> > now_and_ready_to_draw_bins; - std::vector<scoped_refptr<Tile> > now_bins; - std::vector<scoped_refptr<Tile> > soon_bins; - std::vector<scoped_refptr<Tile> > eventually_and_active_bins; - std::vector<scoped_refptr<Tile> > eventually_bins; - std::vector<scoped_refptr<Tile> > never_bins; - std::vector<scoped_refptr<Tile> > never_and_active_bins; - - TilePriority priorities[4] = { - TilePriorityForEventualBin(), - TilePriorityForNowBin(), - TilePriority(), - TilePriorityForSoonBin()}; - - PrioritizedTileSet set; - for (int priority = 0; priority < 4; ++priority) { - for (int i = 0; i < 5; ++i) { - scoped_refptr<Tile> tile = CreateTile(); - tile->SetPriority(ACTIVE_TREE, priorities[priority]); - tile->SetPriority(PENDING_TREE, priorities[priority]); - - now_and_ready_to_draw_bins.push_back(tile); - now_bins.push_back(tile); - soon_bins.push_back(tile); - eventually_and_active_bins.push_back(tile); - eventually_bins.push_back(tile); - never_bins.push_back(tile); - never_and_active_bins.push_back(tile); - - set.InsertTile(tile, NOW_AND_READY_TO_DRAW_BIN); - set.InsertTile(tile, NOW_BIN); - set.InsertTile(tile, SOON_BIN); - set.InsertTile(tile, EVENTUALLY_AND_ACTIVE_BIN); - set.InsertTile(tile, EVENTUALLY_BIN); - set.InsertTile(tile, NEVER_BIN); - set.InsertTile(tile, NEVER_AND_ACTIVE_BIN); - } - } - - PrioritizedTileSet::Iterator it(&set, true); - std::vector<scoped_refptr<Tile> >::iterator vector_it; - - // Now and ready are not sorted. - for (vector_it = now_and_ready_to_draw_bins.begin(); - vector_it != now_and_ready_to_draw_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Now bins are sorted. - std::sort(now_bins.begin(), now_bins.end(), BinComparator()); - for (vector_it = now_bins.begin(); vector_it != now_bins.end(); ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Soon bins are sorted. - std::sort(soon_bins.begin(), soon_bins.end(), BinComparator()); - for (vector_it = soon_bins.begin(); vector_it != soon_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Eventually and active bins are sorted. - std::sort(eventually_and_active_bins.begin(), - eventually_and_active_bins.end(), - BinComparator()); - for (vector_it = eventually_and_active_bins.begin(); - vector_it != eventually_and_active_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Eventually bins are sorted. - std::sort(eventually_bins.begin(), eventually_bins.end(), BinComparator()); - for (vector_it = eventually_bins.begin(); vector_it != eventually_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Never and active bins are sorted. - std::sort(never_and_active_bins.begin(), - never_and_active_bins.end(), - BinComparator()); - for (vector_it = never_and_active_bins.begin(); - vector_it != never_and_active_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Never bins are sorted. - std::sort(never_bins.begin(), never_bins.end(), BinComparator()); - for (vector_it = never_bins.begin(); vector_it != never_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - EXPECT_FALSE(it); -} - -TEST_F(PrioritizedTileSetTest, ManyTilesForEachBinDisablePriority) { - // Aggregate test with many tiles for each of the bins. Tiles should - // appear in order, until DisablePriorityOrdering is called. After that - // tiles should appear in the order they were inserted. - - std::vector<scoped_refptr<Tile> > now_and_ready_to_draw_bins; - std::vector<scoped_refptr<Tile> > now_bins; - std::vector<scoped_refptr<Tile> > soon_bins; - std::vector<scoped_refptr<Tile> > eventually_and_active_bins; - std::vector<scoped_refptr<Tile> > eventually_bins; - std::vector<scoped_refptr<Tile> > never_bins; - std::vector<scoped_refptr<Tile> > never_and_active_bins; - - TilePriority priorities[4] = { - TilePriorityForEventualBin(), - TilePriorityForNowBin(), - TilePriority(), - TilePriorityForSoonBin()}; - - PrioritizedTileSet set; - for (int priority = 0; priority < 4; ++priority) { - for (int i = 0; i < 5; ++i) { - scoped_refptr<Tile> tile = CreateTile(); - tile->SetPriority(ACTIVE_TREE, priorities[priority]); - tile->SetPriority(PENDING_TREE, priorities[priority]); - - now_and_ready_to_draw_bins.push_back(tile); - now_bins.push_back(tile); - soon_bins.push_back(tile); - eventually_and_active_bins.push_back(tile); - eventually_bins.push_back(tile); - never_bins.push_back(tile); - never_and_active_bins.push_back(tile); - - set.InsertTile(tile, NOW_AND_READY_TO_DRAW_BIN); - set.InsertTile(tile, NOW_BIN); - set.InsertTile(tile, SOON_BIN); - set.InsertTile(tile, EVENTUALLY_AND_ACTIVE_BIN); - set.InsertTile(tile, EVENTUALLY_BIN); - set.InsertTile(tile, NEVER_BIN); - set.InsertTile(tile, NEVER_AND_ACTIVE_BIN); - } - } - - PrioritizedTileSet::Iterator it(&set, true); - std::vector<scoped_refptr<Tile> >::iterator vector_it; - - // Now and ready are not sorted. - for (vector_it = now_and_ready_to_draw_bins.begin(); - vector_it != now_and_ready_to_draw_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Now bins are sorted. - std::sort(now_bins.begin(), now_bins.end(), BinComparator()); - for (vector_it = now_bins.begin(); vector_it != now_bins.end(); ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Soon bins are sorted. - std::sort(soon_bins.begin(), soon_bins.end(), BinComparator()); - for (vector_it = soon_bins.begin(); vector_it != soon_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // After we disable priority ordering, we already have sorted the next vector. - it.DisablePriorityOrdering(); - - // Eventually and active bins are sorted. - std::sort(eventually_and_active_bins.begin(), - eventually_and_active_bins.end(), - BinComparator()); - for (vector_it = eventually_and_active_bins.begin(); - vector_it != eventually_and_active_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Eventually bins are not sorted. - for (vector_it = eventually_bins.begin(); vector_it != eventually_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Never and active bins are not sorted. - for (vector_it = never_and_active_bins.begin(); - vector_it != never_and_active_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - // Never bins are not sorted. - for (vector_it = never_bins.begin(); vector_it != never_bins.end(); - ++vector_it) { - EXPECT_TRUE(*vector_it == *it); - ++it; - } - - EXPECT_FALSE(it); -} - TEST_F(PrioritizedTileSetTest, TilesForFirstAndLastBins) { - // Make sure that if we have empty lists between two non-empty lists, - // we just get two tiles from the iterator. - scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile(); scoped_refptr<Tile> never_bin = CreateTile(); @@ -643,8 +386,10 @@ TEST_F(PrioritizedTileSetTest, TilesForFirstAndLastBins) { set.InsertTile(never_bin, NEVER_BIN); set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN); + set.Sort(); + // Only two tiles should appear and they should appear in order. - PrioritizedTileSet::Iterator it(&set, true); + PrioritizedTileSet::PriorityIterator it(&set); EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get()); ++it; EXPECT_TRUE(*it == never_bin.get()); @@ -653,8 +398,6 @@ TEST_F(PrioritizedTileSetTest, TilesForFirstAndLastBins) { } TEST_F(PrioritizedTileSetTest, MultipleIterators) { - // Ensure that multiple iterators don't interfere with each other. - scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile(); scoped_refptr<Tile> now_bin = CreateTile(); scoped_refptr<Tile> soon_bin = CreateTile(); @@ -668,8 +411,10 @@ TEST_F(PrioritizedTileSetTest, MultipleIterators) { set.InsertTile(never_bin, NEVER_BIN); set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN); + set.Sort(); + // Tiles should appear in order. - PrioritizedTileSet::Iterator it(&set, true); + PrioritizedTileSet::PriorityIterator it(&set); EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get()); ++it; EXPECT_TRUE(*it == now_bin.get()); @@ -683,7 +428,7 @@ TEST_F(PrioritizedTileSetTest, MultipleIterators) { EXPECT_FALSE(it); // Creating multiple iterators shouldn't affect old iterators. - PrioritizedTileSet::Iterator second_it(&set, true); + PrioritizedTileSet::PriorityIterator second_it(&set); EXPECT_TRUE(second_it); EXPECT_FALSE(it); @@ -693,7 +438,7 @@ TEST_F(PrioritizedTileSetTest, MultipleIterators) { EXPECT_TRUE(second_it); EXPECT_FALSE(it); - PrioritizedTileSet::Iterator third_it(&set, true); + PrioritizedTileSet::PriorityIterator third_it(&set); EXPECT_TRUE(third_it); ++second_it; ++second_it; @@ -716,7 +461,7 @@ TEST_F(PrioritizedTileSetTest, MultipleIterators) { set.Clear(); - PrioritizedTileSet::Iterator empty_it(&set, true); + PrioritizedTileSet::PriorityIterator empty_it(&set); EXPECT_FALSE(empty_it); } diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc index 5835db565d3..06bc1fbe8fd 100644 --- a/chromium/cc/resources/resource_pool.cc +++ b/chromium/cc/resources/resource_pool.cc @@ -31,19 +31,20 @@ ResourcePool::ResourcePool(ResourceProvider* resource_provider) : resource_provider_(resource_provider), max_memory_usage_bytes_(0), max_unused_memory_usage_bytes_(0), + max_resource_count_(0), memory_usage_bytes_(0), unused_memory_usage_bytes_(0), - num_resources_limit_(0) { + resource_count_(0) { } ResourcePool::~ResourcePool() { - SetMemoryUsageLimits(0, 0, 0); + SetResourceUsageLimits(0, 0, 0); } scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource( gfx::Size size, GLenum format) { - for (ResourceList::iterator it = resources_.begin(); - it != resources_.end(); ++it) { + for (ResourceList::iterator it = unused_resources_.begin(); + it != unused_resources_.end(); ++it) { Resource* resource = *it; // TODO(epenner): It would be nice to DCHECK that this @@ -57,14 +58,13 @@ scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource( if (resource->format() != format) continue; - resources_.erase(it); + unused_resources_.erase(it); unused_memory_usage_bytes_ -= resource->bytes(); return make_scoped_ptr(resource); } // Create new resource. - Resource* resource = new Resource( - resource_provider_, size, format); + Resource* resource = new Resource(resource_provider_, size, format); // Extend all read locks on all resources until the resource is // finished being used, such that we know when resources are @@ -72,44 +72,51 @@ scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource( resource_provider_->EnableReadLockFences(resource->id(), true); memory_usage_bytes_ += resource->bytes(); + ++resource_count_; return make_scoped_ptr(resource); } void ResourcePool::ReleaseResource( scoped_ptr<ResourcePool::Resource> resource) { - if (MemoryUsageTooHigh()) { + if (ResourceUsageTooHigh()) { memory_usage_bytes_ -= resource->bytes(); + --resource_count_; return; } unused_memory_usage_bytes_ += resource->bytes(); - resources_.push_back(resource.release()); + unused_resources_.push_back(resource.release()); } -void ResourcePool::SetMemoryUsageLimits( +void ResourcePool::SetResourceUsageLimits( size_t max_memory_usage_bytes, size_t max_unused_memory_usage_bytes, - size_t num_resources_limit) { + size_t max_resource_count) { max_memory_usage_bytes_ = max_memory_usage_bytes; max_unused_memory_usage_bytes_ = max_unused_memory_usage_bytes; - num_resources_limit_ = num_resources_limit; + max_resource_count_ = max_resource_count; - while (!resources_.empty()) { - if (!MemoryUsageTooHigh()) + ReduceResourceUsage(); +} + +void ResourcePool::ReduceResourceUsage() { + while (!unused_resources_.empty()) { + if (!ResourceUsageTooHigh()) break; // MRU eviction pattern as least recently used is less likely to // be blocked by read lock fence. - Resource* resource = resources_.back(); - resources_.pop_back(); + Resource* resource = unused_resources_.back(); + unused_resources_.pop_back(); memory_usage_bytes_ -= resource->bytes(); unused_memory_usage_bytes_ -= resource->bytes(); + --resource_count_; delete resource; } } -bool ResourcePool::MemoryUsageTooHigh() { - if (resources_.size() > num_resources_limit_) +bool ResourcePool::ResourceUsageTooHigh() { + if (resource_count_ > max_resource_count_) return true; if (memory_usage_bytes_ > max_memory_usage_bytes_) return true; diff --git a/chromium/cc/resources/resource_pool.h b/chromium/cc/resources/resource_pool.h index 309bf33f30b..f6bb8652476 100644 --- a/chromium/cc/resources/resource_pool.h +++ b/chromium/cc/resources/resource_pool.h @@ -40,33 +40,35 @@ class CC_EXPORT ResourcePool { GLenum format); void ReleaseResource(scoped_ptr<ResourcePool::Resource>); - void SetMemoryUsageLimits(size_t max_memory_usage_bytes, - size_t max_unused_memory_usage_bytes, - size_t num_resources_limit); + void SetResourceUsageLimits(size_t max_memory_usage_bytes, + size_t max_unused_memory_usage_bytes, + size_t max_resource_count); + + void ReduceResourceUsage(); - size_t total_memory_usage_bytes() const { - return memory_usage_bytes_; - } size_t acquired_memory_usage_bytes() const { return memory_usage_bytes_ - unused_memory_usage_bytes_; } - size_t NumResources() const { return resources_.size(); } + size_t acquired_resource_count() const { + return resource_count_ - unused_resources_.size(); + } protected: explicit ResourcePool(ResourceProvider* resource_provider); - bool MemoryUsageTooHigh(); + bool ResourceUsageTooHigh(); private: ResourceProvider* resource_provider_; size_t max_memory_usage_bytes_; size_t max_unused_memory_usage_bytes_; + size_t max_resource_count_; size_t memory_usage_bytes_; size_t unused_memory_usage_bytes_; - size_t num_resources_limit_; + size_t resource_count_; typedef std::list<Resource*> ResourceList; - ResourceList resources_; + ResourceList unused_resources_; DISALLOW_COPY_AND_ASSIGN(ResourcePool); }; diff --git a/chromium/cc/resources/resource_provider_unittest.cc b/chromium/cc/resources/resource_provider_unittest.cc index ad6b3d36f2a..a23af0b577c 100644 --- a/chromium/cc/resources/resource_provider_unittest.cc +++ b/chromium/cc/resources/resource_provider_unittest.cc @@ -11,10 +11,10 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "cc/base/scoped_ptr_deque.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/output/output_surface.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/cc/resources/resource_update_controller_unittest.cc b/chromium/cc/resources/resource_update_controller_unittest.cc index 9dcb23ca124..1060801934b 100644 --- a/chromium/cc/resources/resource_update_controller_unittest.cc +++ b/chromium/cc/resources/resource_update_controller_unittest.cc @@ -5,11 +5,11 @@ #include "cc/resources/resource_update_controller.h" #include "base/test/test_simple_task_runner.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/resources/prioritized_resource_manager.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_proxy.h" #include "cc/test/scheduler_test_common.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "cc/test/tiled_layer_test_common.h" #include "cc/trees/single_thread_proxy.h" // For DebugScopedSetImplThread #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/cc/resources/tile_manager.cc b/chromium/cc/resources/tile_manager.cc index 7cf5096ce3b..e6850bcfd84 100644 --- a/chromium/cc/resources/tile_manager.cc +++ b/chromium/cc/resources/tile_manager.cc @@ -175,7 +175,7 @@ TileManager::~TileManager() { void TileManager::SetGlobalState( const GlobalStateThatImpactsTilePriority& global_state) { global_state_ = global_state; - resource_pool_->SetMemoryUsageLimits( + resource_pool_->SetResourceUsageLimits( global_state_.memory_limit_in_bytes, global_state_.unused_memory_limit_in_bytes, global_state_.num_resources_limit); @@ -347,6 +347,7 @@ void TileManager::GetPrioritizedTileSet(PrioritizedTileSet* tiles) { TRACE_EVENT0("cc", "TileManager::GetPrioritizedTileSet"); GetTilesWithAssignedBins(tiles); + tiles->Sort(); } void TileManager::ManageTiles() { @@ -362,16 +363,12 @@ void TileManager::ManageTiles() { &tiles_that_need_to_be_rasterized); CleanUpUnusedImageDecodeTasks(); - // Finally, schedule rasterizer tasks. - ScheduleTasks(tiles_that_need_to_be_rasterized); - TRACE_EVENT_INSTANT1( "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, "state", TracedValue::FromValue(BasicStateAsValue().release())); - TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, - resource_pool_->total_memory_usage_bytes() - - resource_pool_->acquired_memory_usage_bytes()); + // Finally, schedule rasterizer tasks. + ScheduleTasks(tiles_that_need_to_be_rasterized); } bool TileManager::UpdateVisibleTiles() { @@ -394,11 +391,9 @@ bool TileManager::UpdateVisibleTiles() { void TileManager::GetMemoryStats( size_t* memory_required_bytes, size_t* memory_nice_to_have_bytes, - size_t* memory_allocated_bytes, size_t* memory_used_bytes) const { *memory_required_bytes = 0; *memory_nice_to_have_bytes = 0; - *memory_allocated_bytes = resource_pool_->total_memory_usage_bytes(); *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); @@ -445,16 +440,13 @@ scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { size_t memory_required_bytes; size_t memory_nice_to_have_bytes; - size_t memory_allocated_bytes; size_t memory_used_bytes; GetMemoryStats(&memory_required_bytes, &memory_nice_to_have_bytes, - &memory_allocated_bytes, &memory_used_bytes); requirements->SetInteger("memory_required_bytes", memory_required_bytes); requirements->SetInteger("memory_nice_to_have_bytes", memory_nice_to_have_bytes); - requirements->SetInteger("memory_allocated_bytes", memory_allocated_bytes); requirements->SetInteger("memory_used_bytes", memory_used_bytes); return requirements.PassAs<base::Value>(); } @@ -487,7 +479,7 @@ void TileManager::AssignGpuMemoryToTiles( // the needs-to-be-rasterized queue. size_t bytes_releasable = 0; size_t resources_releasable = 0; - for (PrioritizedTileSet::Iterator it(tiles, false); + for (PrioritizedTileSet::PriorityIterator it(tiles); it; ++it) { const Tile* tile = *it; @@ -509,9 +501,10 @@ void TileManager::AssignGpuMemoryToTiles( static_cast<int64>(bytes_releasable) + static_cast<int64>(global_state_.memory_limit_in_bytes) - static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); - int resources_available = resources_releasable + - global_state_.num_resources_limit - - resource_pool_->NumResources(); + int resources_available = + resources_releasable + + global_state_.num_resources_limit - + resource_pool_->acquired_resource_count(); size_t bytes_allocatable = std::max(static_cast<int64>(0), bytes_available); @@ -523,7 +516,7 @@ void TileManager::AssignGpuMemoryToTiles( bool oomed = false; unsigned schedule_priority = 1u; - for (PrioritizedTileSet::Iterator it(tiles, true); + for (PrioritizedTileSet::PriorityIterator it(tiles); it; ++it) { Tile* tile = *it; @@ -606,7 +599,6 @@ void TileManager::AssignGpuMemoryToTiles( all_tiles_that_need_to_be_rasterized_have_memory_ = false; if (tile->required_for_activation()) all_tiles_required_for_activation_have_memory_ = false; - it.DisablePriorityOrdering(); continue; } @@ -709,6 +701,10 @@ void TileManager::ScheduleTasks( tasks.Append(tile_version.raster_task_, tile->required_for_activation()); } + // We must reduce the amount of unused resoruces before calling + // ScheduleTasks to prevent usage from rising above limits. + resource_pool_->ReduceResourceUsage(); + // Schedule running of |tasks|. This replaces any previously // scheduled tasks and effectively cancels all tasks not present // in |tasks|. diff --git a/chromium/cc/resources/tile_manager.h b/chromium/cc/resources/tile_manager.h index 7957fc823f2..2e226c9999d 100644 --- a/chromium/cc/resources/tile_manager.h +++ b/chromium/cc/resources/tile_manager.h @@ -69,7 +69,6 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient { scoped_ptr<base::Value> AllTilesAsValue() const; void GetMemoryStats(size_t* memory_required_bytes, size_t* memory_nice_to_have_bytes, - size_t* memory_allocated_bytes, size_t* memory_used_bytes) const; const MemoryHistory::Entry& memory_stats_from_last_assign() const { diff --git a/chromium/cc/resources/video_resource_updater_unittest.cc b/chromium/cc/resources/video_resource_updater_unittest.cc index ca6ebd0d117..ff574fff7fb 100644 --- a/chromium/cc/resources/video_resource_updater_unittest.cc +++ b/chromium/cc/resources/video_resource_updater_unittest.cc @@ -5,9 +5,9 @@ #include "cc/resources/video_resource_updater.h" #include "base/memory/shared_memory.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/resources/resource_provider.h" #include "cc/test/fake_output_surface.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "media/base/video_frame.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/cc/scheduler/delay_based_time_source.cc b/chromium/cc/scheduler/delay_based_time_source.cc index a5b6f738df8..44003970b35 100644 --- a/chromium/cc/scheduler/delay_based_time_source.cc +++ b/chromium/cc/scheduler/delay_based_time_source.cc @@ -17,10 +17,10 @@ namespace cc { namespace { -// kDoubleTickDivisor prevents ticks from running within the specified +// kDoubleTickThreshold prevents ticks from running within the specified // fraction of an interval. This helps account for jitter in the timebase as // well as quick timer reactivation. -static const int kDoubleTickDivisor = 2; +static const double kDoubleTickThreshold = 0.25; // kIntervalChangeThreshold is the fraction of the interval that will trigger an // immediate interval change. kPhaseChangeThreshold is the fraction of the @@ -42,42 +42,43 @@ scoped_refptr<DelayBasedTimeSource> DelayBasedTimeSource::Create( DelayBasedTimeSource::DelayBasedTimeSource( base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner) : client_(NULL), - last_tick_time_(base::TimeTicks() - interval), + has_tick_target_(false), current_parameters_(interval, base::TimeTicks()), next_parameters_(interval, base::TimeTicks()), - active_(false), + state_(STATE_INACTIVE), task_runner_(task_runner), weak_factory_(this) {} DelayBasedTimeSource::~DelayBasedTimeSource() {} -base::TimeTicks DelayBasedTimeSource::SetActive(bool active) { +void DelayBasedTimeSource::SetActive(bool active) { TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active); - if (active == active_) - return base::TimeTicks(); - active_ = active; - - if (!active_) { + if (!active) { + state_ = STATE_INACTIVE; weak_factory_.InvalidateWeakPtrs(); - return base::TimeTicks(); + return; } - PostNextTickTask(Now()); + if (state_ == STATE_STARTING || state_ == STATE_ACTIVE) + return; - // Determine if there was a tick that was missed while not active. - base::TimeTicks last_tick_time_if_always_active = - current_parameters_.tick_target - current_parameters_.interval; - base::TimeTicks new_tick_time_threshold = - last_tick_time_ + current_parameters_.interval / kDoubleTickDivisor; - if (last_tick_time_if_always_active > new_tick_time_threshold) { - last_tick_time_ = last_tick_time_if_always_active; - return last_tick_time_; + if (!has_tick_target_) { + // Becoming active the first time is deferred: we post a 0-delay task. + // When it runs, we use that to establish the timebase, become truly + // active, and fire the first tick. + state_ = STATE_STARTING; + task_runner_->PostTask(FROM_HERE, + base::Bind(&DelayBasedTimeSource::OnTimerFired, + weak_factory_.GetWeakPtr())); + return; } - return base::TimeTicks(); + state_ = STATE_ACTIVE; + + PostNextTickTask(Now()); } -bool DelayBasedTimeSource::Active() const { return active_; } +bool DelayBasedTimeSource::Active() const { return state_ != STATE_INACTIVE; } base::TimeTicks DelayBasedTimeSource::LastTickTime() { return last_tick_time_; } @@ -86,11 +87,17 @@ base::TimeTicks DelayBasedTimeSource::NextTickTime() { } void DelayBasedTimeSource::OnTimerFired() { - DCHECK(active_); + DCHECK(state_ != STATE_INACTIVE); - last_tick_time_ = current_parameters_.tick_target; + base::TimeTicks now = this->Now(); + last_tick_time_ = now; - PostNextTickTask(Now()); + if (state_ == STATE_STARTING) { + SetTimebaseAndInterval(now, current_parameters_.interval); + state_ = STATE_ACTIVE; + } + + PostNextTickTask(now); // Fire the tick. if (client_) @@ -105,8 +112,9 @@ void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase, base::TimeDelta interval) { next_parameters_.interval = interval; next_parameters_.tick_target = timebase; + has_tick_target_ = true; - if (!active_) { + if (state_ != STATE_ACTIVE) { // If we aren't active, there's no need to reset the timer. return; } @@ -117,8 +125,6 @@ void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase, std::abs((interval - current_parameters_.interval).InSecondsF()); double interval_change = interval_delta / interval.InSecondsF(); if (interval_change > kIntervalChangeThreshold) { - TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::IntervalChanged", - TRACE_EVENT_SCOPE_THREAD); SetActive(false); SetActive(true); return; @@ -136,8 +142,6 @@ void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase, fmod(target_delta, interval.InSecondsF()) / interval.InSecondsF(); if (phase_change > kPhaseChangeThreshold && phase_change < (1.0 - kPhaseChangeThreshold)) { - TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::PhaseChanged", - TRACE_EVENT_SCOPE_THREAD); SetActive(false); SetActive(true); return; @@ -203,32 +207,26 @@ base::TimeTicks DelayBasedTimeSource::Now() const { // now=37 tick_target=16.667 new_target=50.000 --> // tick(), PostDelayedTask(floor(50.000-37)) --> PostDelayedTask(13) base::TimeTicks DelayBasedTimeSource::NextTickTarget(base::TimeTicks now) { - const base::TimeDelta epsilon(base::TimeDelta::FromMicroseconds(1)); base::TimeDelta new_interval = next_parameters_.interval; - - // Integer division rounds towards 0, but we always want to round down the - // number of intervals_elapsed, so we need the extra condition here. - int intervals_elapsed; - if (next_parameters_.tick_target < now) { - intervals_elapsed = - (now - next_parameters_.tick_target + new_interval - epsilon) / - new_interval; - } else { - intervals_elapsed = (now - next_parameters_.tick_target) / new_interval; - } - base::TimeTicks new_tick_target = + int intervals_elapsed = + static_cast<int>(floor((now - next_parameters_.tick_target).InSecondsF() / + new_interval.InSecondsF())); + base::TimeTicks last_effective_tick = next_parameters_.tick_target + new_interval * intervals_elapsed; - DCHECK(now <= new_tick_target) + base::TimeTicks new_tick_target = last_effective_tick + new_interval; + DCHECK(now < new_tick_target) << "now = " << now.ToInternalValue() << "; new_tick_target = " << new_tick_target.ToInternalValue() << "; new_interval = " << new_interval.InMicroseconds() << "; tick_target = " << next_parameters_.tick_target.ToInternalValue() - << "; intervals_elapsed = " << intervals_elapsed; + << "; intervals_elapsed = " << intervals_elapsed + << "; last_effective_tick = " << last_effective_tick.ToInternalValue(); // Avoid double ticks when: // 1) Turning off the timer and turning it right back on. // 2) Jittery data is passed to SetTimebaseAndInterval(). - if (new_tick_target - last_tick_time_ <= new_interval / kDoubleTickDivisor) + if (new_tick_target - last_tick_time_ <= + new_interval / static_cast<int>(1.0 / kDoubleTickThreshold)) new_tick_target += new_interval; return new_tick_target; @@ -238,9 +236,10 @@ void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) { base::TimeTicks new_tick_target = NextTickTarget(now); // Post another task *before* the tick and update state - base::TimeDelta delay; - if (now <= new_tick_target) - delay = new_tick_target - now; + base::TimeDelta delay = new_tick_target - now; + DCHECK(delay.InMillisecondsF() <= + next_parameters_.interval.InMillisecondsF() * + (1.0 + kDoubleTickThreshold)); task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&DelayBasedTimeSource::OnTimerFired, weak_factory_.GetWeakPtr()), diff --git a/chromium/cc/scheduler/delay_based_time_source.h b/chromium/cc/scheduler/delay_based_time_source.h index 55aac5a97fb..1dc4d6fff11 100644 --- a/chromium/cc/scheduler/delay_based_time_source.h +++ b/chromium/cc/scheduler/delay_based_time_source.h @@ -27,7 +27,7 @@ class CC_EXPORT DelayBasedTimeSource : public TimeSource { virtual void SetTimebaseAndInterval(base::TimeTicks timebase, base::TimeDelta interval) OVERRIDE; - virtual base::TimeTicks SetActive(bool active) OVERRIDE; + virtual void SetActive(bool active) OVERRIDE; virtual bool Active() const OVERRIDE; // Get the last and next tick times. nextTimeTime() returns null when @@ -47,6 +47,12 @@ class CC_EXPORT DelayBasedTimeSource : public TimeSource { void PostNextTickTask(base::TimeTicks now); void OnTimerFired(); + enum State { + STATE_INACTIVE, + STATE_STARTING, + STATE_ACTIVE, + }; + struct Parameters { Parameters(base::TimeDelta interval, base::TimeTicks tick_target) : interval(interval), tick_target(tick_target) {} @@ -55,6 +61,7 @@ class CC_EXPORT DelayBasedTimeSource : public TimeSource { }; TimeSourceClient* client_; + bool has_tick_target_; base::TimeTicks last_tick_time_; // current_parameters_ should only be written by PostNextTickTask. @@ -64,7 +71,7 @@ class CC_EXPORT DelayBasedTimeSource : public TimeSource { Parameters current_parameters_; Parameters next_parameters_; - bool active_; + State state_; base::SingleThreadTaskRunner* task_runner_; base::WeakPtrFactory<DelayBasedTimeSource> weak_factory_; diff --git a/chromium/cc/scheduler/delay_based_time_source_unittest.cc b/chromium/cc/scheduler/delay_based_time_source_unittest.cc index 77d570f1d92..df84c978e57 100644 --- a/chromium/cc/scheduler/delay_based_time_source_unittest.cc +++ b/chromium/cc/scheduler/delay_based_time_source_unittest.cc @@ -88,7 +88,7 @@ TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyOnRequestedTime) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -109,7 +109,7 @@ TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterRequestedTime) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -122,7 +122,7 @@ TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterRequestedTime) { } // At 60Hz, when the tick returns at exactly 2*interval after the requested next -// time, make sure a 0ms next delay is posted. +// time, make sure a 16ms next delay is posted. TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; @@ -131,7 +131,7 @@ TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -139,7 +139,7 @@ TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime) { timer->SetNow(timer->Now() + 2 * Interval()); task_runner->RunPendingTasks(); - EXPECT_EQ(0, task_runner->NextPendingTaskDelay().InMilliseconds()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); } // At 60Hz, when the tick returns at 2*interval and a bit after the requested @@ -152,7 +152,7 @@ TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterTwiceRequestedTime) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -174,7 +174,7 @@ TEST(DelayBasedTimeSource, NextDelaySaneWhenHalfAfterRequestedTime) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -196,7 +196,7 @@ TEST(DelayBasedTimeSource, SaneHandlingOfJitteryTimebase) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -227,7 +227,7 @@ TEST(DelayBasedTimeSource, HandlesSignificantTimebaseChangesImmediately) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -246,10 +246,10 @@ TEST(DelayBasedTimeSource, HandlesSignificantTimebaseChangesImmediately) { timer->SetTimebaseAndInterval(timer->Now() + jitter, Interval()); EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. - EXPECT_EQ(16 + 7, task_runner->NextPendingTaskDelay().InMilliseconds()); + EXPECT_EQ(7, task_runner->NextPendingTaskDelay().InMilliseconds()); // Tick, then shift timebase by -7ms. - timer->SetNow(timer->Now() + Interval() + jitter); + timer->SetNow(timer->Now() + jitter); task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -271,7 +271,7 @@ TEST(DelayBasedTimeSource, HanldlesSignificantIntervalChangesImmediately) { FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - // Run the first tick. + // Run the first task, as that activates the timer and picks up a timebase. task_runner->RunPendingTasks(); EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); @@ -305,115 +305,6 @@ TEST(DelayBasedTimeSource, HanldlesSignificantIntervalChangesImmediately) { EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); } -TEST(DelayBasedTimeSource, JitteryRuntimeWithFutureTimebases) { - scoped_refptr<base::TestSimpleTaskRunner> task_runner = - new base::TestSimpleTaskRunner; - FakeTimeSourceClient client; - scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); - timer->SetClient(&client); - timer->SetActive(true); - - // Run the first tick. - task_runner->RunPendingTasks(); - EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); - - base::TimeTicks future_timebase = timer->Now() + Interval() * 10; - - // 1ms jitter - base::TimeDelta jitter1 = base::TimeDelta::FromMilliseconds(1); - - // Tick with +1ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() + jitter1); - task_runner->RunPendingTasks(); - EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with 0ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() - jitter1); - task_runner->RunPendingTasks(); - EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with -1ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() - jitter1); - task_runner->RunPendingTasks(); - EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with 0ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() + jitter1); - task_runner->RunPendingTasks(); - EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // 8 ms jitter - base::TimeDelta jitter8 = base::TimeDelta::FromMilliseconds(8); - - // Tick with +8ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() + jitter8); - task_runner->RunPendingTasks(); - EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with 0ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() - jitter8); - task_runner->RunPendingTasks(); - EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with -8ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() - jitter8); - task_runner->RunPendingTasks(); - EXPECT_EQ(24, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with 0ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() + jitter8); - task_runner->RunPendingTasks(); - EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // 15 ms jitter - base::TimeDelta jitter15 = base::TimeDelta::FromMilliseconds(15); - - // Tick with +15ms jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() + jitter15); - task_runner->RunPendingTasks(); - EXPECT_EQ(1, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with 0ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() - jitter15); - task_runner->RunPendingTasks(); - EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with -15ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() - jitter15); - task_runner->RunPendingTasks(); - EXPECT_EQ(31, task_runner->NextPendingTaskDelay().InMilliseconds()); - - // Tick with 0ms of jitter - future_timebase += Interval(); - timer->SetTimebaseAndInterval(future_timebase, Interval()); - timer->SetNow(timer->Now() + Interval() + jitter15); - task_runner->RunPendingTasks(); - EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); -} - TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) { int num_iterations = 10; diff --git a/chromium/cc/scheduler/frame_rate_controller.cc b/chromium/cc/scheduler/frame_rate_controller.cc index 54c1bdaf48f..4844b16faee 100644 --- a/chromium/cc/scheduler/frame_rate_controller.cc +++ b/chromium/cc/scheduler/frame_rate_controller.cc @@ -70,16 +70,11 @@ BeginFrameArgs FrameRateController::SetActive(bool active) { if (active_ == active) return BeginFrameArgs(); TRACE_EVENT1("cc", "FrameRateController::SetActive", "active", active); + bool just_activated = active && !active_; active_ = active; if (is_time_source_throttling_) { - base::TimeTicks missed_tick_time = time_source_->SetActive(active); - if (!missed_tick_time.is_null()) { - base::TimeTicks deadline = NextTickTime(); - return BeginFrameArgs::Create(missed_tick_time, - deadline, - interval_); - } + time_source_->SetActive(active); } else { if (active) PostManualTick(); @@ -87,6 +82,12 @@ BeginFrameArgs FrameRateController::SetActive(bool active) { weak_factory_.InvalidateWeakPtrs(); } + if (just_activated) { + // TODO(brianderson): Use an adaptive parent compositor deadline. + base::TimeTicks frame_time = NextTickTime() - interval_; + base::TimeTicks deadline = NextTickTime(); + return BeginFrameArgs::Create(frame_time, deadline, interval_); + } return BeginFrameArgs(); } diff --git a/chromium/cc/scheduler/frame_rate_controller.h b/chromium/cc/scheduler/frame_rate_controller.h index b68c73db0c8..ed769238fe3 100644 --- a/chromium/cc/scheduler/frame_rate_controller.h +++ b/chromium/cc/scheduler/frame_rate_controller.h @@ -61,6 +61,12 @@ class CC_EXPORT FrameRateController { int MaxSwapsPending() const { return max_swaps_pending_; } int NumSwapsPendingForTesting() const { return num_frames_pending_; } + // This returns null for unthrottled frame-rate. + base::TimeTicks NextTickTime(); + + // This returns now for unthrottled frame-rate. + base::TimeTicks LastTickTime(); + void SetTimebaseAndInterval(base::TimeTicks timebase, base::TimeDelta interval); void SetDeadlineAdjustment(base::TimeDelta delta); @@ -72,11 +78,6 @@ class CC_EXPORT FrameRateController { void PostManualTick(); void ManualTick(); - // This returns null for unthrottled frame-rate. - base::TimeTicks NextTickTime(); - // This returns now for unthrottled frame-rate. - base::TimeTicks LastTickTime(); - FrameRateControllerClient* client_; int num_frames_pending_; int max_swaps_pending_; diff --git a/chromium/cc/scheduler/texture_uploader_unittest.cc b/chromium/cc/scheduler/texture_uploader_unittest.cc index 05959172f50..f4b4ce69b2e 100644 --- a/chromium/cc/scheduler/texture_uploader_unittest.cc +++ b/chromium/cc/scheduler/texture_uploader_unittest.cc @@ -5,8 +5,8 @@ #include "cc/scheduler/texture_uploader.h" #include "cc/base/util.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/resources/prioritized_resource.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/khronos/GLES2/gl2.h" diff --git a/chromium/cc/scheduler/time_source.h b/chromium/cc/scheduler/time_source.h index e45ffbb95aa..c02d4901a97 100644 --- a/chromium/cc/scheduler/time_source.h +++ b/chromium/cc/scheduler/time_source.h @@ -27,12 +27,7 @@ class TimeSourceClient { class CC_EXPORT TimeSource : public base::RefCounted<TimeSource> { public: virtual void SetClient(TimeSourceClient* client) = 0; - - // If transitioning from not active to active, SetActive will return the - // timestamp of the most recenly missed tick that did not have OnTimerTick - // called. - virtual base::TimeTicks SetActive(bool active) = 0; - + virtual void SetActive(bool active) = 0; virtual bool Active() const = 0; virtual void SetTimebaseAndInterval(base::TimeTicks timebase, base::TimeDelta interval) = 0; diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 720febd7fc7..9519e745af4 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -327,11 +327,9 @@ void LayerTreeHostImpl::ManageTiles() { size_t memory_required_bytes; size_t memory_nice_to_have_bytes; - size_t memory_allocated_bytes; size_t memory_used_bytes; tile_manager_->GetMemoryStats(&memory_required_bytes, &memory_nice_to_have_bytes, - &memory_allocated_bytes, &memory_used_bytes); SendManagedMemoryStats(memory_required_bytes, memory_nice_to_have_bytes, @@ -1529,6 +1527,11 @@ void LayerTreeHostImpl::SetVisible(bool visible) { DidVisibilityChange(this, visible_); EnforceManagedMemoryPolicy(ActualManagedMemoryPolicy()); + // Evict tiles immediately if invisible since this tab may never get another + // draw or timer tick. + if (!visible_) + ManageTiles(); + if (!renderer_) return; @@ -2502,9 +2505,7 @@ void LayerTreeHostImpl::CreateUIResource( if (id) DeleteUIResource(uid); id = resource_provider_->CreateResource( - bitmap->GetSize(), - resource_provider_->best_texture_format(), - ResourceProvider::TextureUsageAny); + bitmap->GetSize(), GL_RGBA, ResourceProvider::TextureUsageAny); ui_resource_map_[uid] = id; resource_provider_->SetPixels(id, diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index 764a9cf93de..ab81c672b8c 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -10,7 +10,6 @@ #include "base/command_line.h" #include "base/containers/hash_tables.h" #include "cc/base/math_util.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/input/top_controls_manager.h" #include "cc/layers/delegated_renderer_layer_impl.h" #include "cc/layers/heads_up_display_layer_impl.h" @@ -40,6 +39,7 @@ #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_test_common.h" #include "cc/test/render_pass_test_common.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "media/base/media.h" diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index 55841e52e70..b18a88a7865 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -1111,7 +1111,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); // Verify atomicity of commits and reuse of textures. -class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { +class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest { public: virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { // Make sure partial texture updates are turned off. @@ -1162,18 +1162,19 @@ class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); break; case 1: - // Number of textures should be one for scrollbar layer since it was - // requested and deleted on the impl-thread, and double for the content - // layer since its first texture is used by impl thread and cannot by - // used for update. - ASSERT_EQ(3u, context->NumTextures()); - // Number of textures used for commit should be one for each layer. + // Number of textures should be doubled as the first textures + // are used by impl thread and cannot by used for update. + ASSERT_EQ(4u, context->NumTextures()); + // Number of textures used for commit should still be + // one for each layer. EXPECT_EQ(2u, context->NumUsedTextures()); // First textures should not have been used. EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); - EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); + EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); // New textures should have been used. EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); + EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); + context->ResetUsedTextures(); PostSetNeedsCommitToMainThread(); break; @@ -1208,68 +1209,14 @@ class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { virtual void AfterTest() OVERRIDE {} - protected: + private: FakeContentLayerClient client_; scoped_refptr<FakeContentLayer> layer_; scoped_refptr<FakeScrollbarLayer> scrollbar_; int drew_frame_; }; -MULTI_THREAD_DIRECT_RENDERER_TEST_F( - LayerTreeHostTestDirectRendererAtomicCommit); - -class LayerTreeHostTestDelegatingRendererAtomicCommit - : public LayerTreeHostTestDirectRendererAtomicCommit { - public: - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { - ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates); - - TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>( - impl->output_surface()->context3d()); - - switch (impl->active_tree()->source_frame_number()) { - case 0: - // Number of textures should be one for each layer - ASSERT_EQ(2u, context->NumTextures()); - // Number of textures used for commit should be one for each layer. - EXPECT_EQ(2u, context->NumUsedTextures()); - // Verify that used texture is correct. - EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); - EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); - context->ResetUsedTextures(); - PostSetNeedsCommitToMainThread(); - break; - case 1: - // Number of textures should be doubled as the first context layer - // texture is being used by the impl-thread and cannot be used for - // update. The scrollbar behavior is different direct renderer because - // UI resource deletion with delegating renderer occurs after tree - // activation. - ASSERT_EQ(4u, context->NumTextures()); - // Number of textures used for commit should still be - // one for each layer. - EXPECT_EQ(2u, context->NumUsedTextures()); - // First textures should not have been used. - EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); - EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); - // New textures should have been used. - EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); - EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); - context->ResetUsedTextures(); - PostSetNeedsCommitToMainThread(); - break; - case 2: - EndTest(); - break; - default: - NOTREACHED(); - break; - } - } -}; - -MULTI_THREAD_DELEGATING_RENDERER_TEST_F( - LayerTreeHostTestDelegatingRendererAtomicCommit); +MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit); static void SetLayerPropertiesForTesting(Layer* layer, Layer* parent, diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index 3404c1ea9df..1787d31ddf3 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -5,8 +5,6 @@ #include "cc/trees/layer_tree_host.h" #include "base/basictypes.h" -#include "cc/debug/test_context_provider.h" -#include "cc/debug/test_web_graphics_context_3d.h" #include "cc/layers/content_layer.h" #include "cc/layers/heads_up_display_layer.h" #include "cc/layers/io_surface_layer.h" @@ -21,6 +19,7 @@ #include "cc/test/fake_content_layer.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_content_layer_impl.h" +#include "cc/test/fake_context_provider.h" #include "cc/test/fake_delegated_renderer_layer.h" #include "cc/test/fake_delegated_renderer_layer_impl.h" #include "cc/test/fake_layer_tree_host_client.h" @@ -31,6 +30,7 @@ #include "cc/test/fake_video_frame_provider.h" #include "cc/test/layer_tree_test.h" #include "cc/test/render_pass_test_common.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" @@ -141,7 +141,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { if (!offscreen_contexts_main_thread_.get() || offscreen_contexts_main_thread_->DestroyedOnMainThread()) { - offscreen_contexts_main_thread_ = TestContextProvider::Create( + offscreen_contexts_main_thread_ = FakeContextProvider::Create( base::Bind(&LayerTreeHostContextTest::CreateOffscreenContext3d, base::Unretained(this))); if (offscreen_contexts_main_thread_.get() && @@ -157,7 +157,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { if (!offscreen_contexts_compositor_thread_.get() || offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) { - offscreen_contexts_compositor_thread_ = TestContextProvider::Create( + offscreen_contexts_compositor_thread_ = FakeContextProvider::Create( base::Bind(&LayerTreeHostContextTest::CreateOffscreenContext3d, base::Unretained(this))); } @@ -236,8 +236,8 @@ class LayerTreeHostContextTest : public LayerTreeTest { bool context_should_support_io_surface_; bool fallback_context_works_; - scoped_refptr<TestContextProvider> offscreen_contexts_main_thread_; - scoped_refptr<TestContextProvider> offscreen_contexts_compositor_thread_; + scoped_refptr<FakeContextProvider> offscreen_contexts_main_thread_; + scoped_refptr<FakeContextProvider> offscreen_contexts_compositor_thread_; }; class LayerTreeHostContextTestLostContextSucceeds |