blob: 2e188084f46078bc141a42f355a82d199d09b1a5 [file] [log] [blame]
// 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.
#include "cc/layers/nine_patch_layer.h"
#include "cc/debug/overdraw_metrics.h"
#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource_provider.h"
#include "cc/resources/resource_update_queue.h"
#include "cc/scheduler/texture_uploader.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/occlusion_tracker.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
using ::testing::Mock;
using ::testing::_;
using ::testing::AtLeast;
using ::testing::AnyNumber;
namespace cc {
namespace {
class MockLayerTreeHost : public LayerTreeHost {
public:
explicit MockLayerTreeHost(LayerTreeHostClient* client)
: LayerTreeHost(client, LayerTreeSettings()) {
Initialize(NULL);
}
};
class NinePatchLayerTest : public testing::Test {
public:
NinePatchLayerTest() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {}
cc::Proxy* Proxy() const { return layer_tree_host_->proxy(); }
protected:
virtual void SetUp() {
layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
}
virtual void TearDown() {
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}
scoped_ptr<MockLayerTreeHost> layer_tree_host_;
FakeLayerTreeHostClient fake_client_;
};
TEST_F(NinePatchLayerTest, TriggerFullUploadOnceWhenChangingBitmap) {
scoped_refptr<NinePatchLayer> test_layer = NinePatchLayer::Create();
ASSERT_TRUE(test_layer.get());
test_layer->SetIsDrawable(true);
test_layer->SetBounds(gfx::Size(100, 100));
layer_tree_host_->SetRootLayer(test_layer);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
layer_tree_host_->InitializeOutputSurfaceIfNeeded();
PriorityCalculator calculator;
ResourceUpdateQueue queue;
OcclusionTracker occlusion_tracker(gfx::Rect(), false);
// No bitmap set should not trigger any uploads.
test_layer->SavePaintProperties();
test_layer->SetTexturePriorities(calculator);
test_layer->Update(&queue, &occlusion_tracker);
EXPECT_EQ(0u, queue.FullUploadSize());
EXPECT_EQ(0u, queue.PartialUploadSize());
// Setting a bitmap set should trigger a single full upload.
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
bitmap.allocPixels();
test_layer->SetBitmap(bitmap, gfx::Rect(5, 5, 1, 1));
test_layer->SavePaintProperties();
test_layer->SetTexturePriorities(calculator);
test_layer->Update(&queue, &occlusion_tracker);
EXPECT_EQ(1u, queue.FullUploadSize());
EXPECT_EQ(0u, queue.PartialUploadSize());
ResourceUpdate params = queue.TakeFirstFullUpload();
EXPECT_TRUE(params.texture != NULL);
// Upload the texture.
layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
1024 * 1024);
layer_tree_host_->contents_texture_manager()->PrioritizeTextures();
FakeOutputSurfaceClient output_surface_client;
scoped_ptr<OutputSurface> output_surface;
scoped_ptr<ResourceProvider> resource_provider;
{
DebugScopedSetImplThread impl_thread(Proxy());
DebugScopedSetMainThreadBlocked main_thread_blocked(Proxy());
output_surface = FakeOutputSurface::Create3d();
CHECK(output_surface->BindToClient(&output_surface_client));
resource_provider =
ResourceProvider::Create(output_surface.get(), 0, false);
params.texture->AcquireBackingTexture(resource_provider.get());
ASSERT_TRUE(params.texture->have_backing_texture());
}
// Nothing changed, so no repeated upload.
test_layer->SavePaintProperties();
test_layer->SetTexturePriorities(calculator);
test_layer->Update(&queue, &occlusion_tracker);
EXPECT_EQ(0u, queue.FullUploadSize());
EXPECT_EQ(0u, queue.PartialUploadSize());
{
DebugScopedSetImplThread impl_thread(Proxy());
DebugScopedSetMainThreadBlocked main_thread_blocked(Proxy());
layer_tree_host_->contents_texture_manager()->ClearAllMemory(
resource_provider.get());
}
// Reupload after eviction
test_layer->SavePaintProperties();
test_layer->SetTexturePriorities(calculator);
test_layer->Update(&queue, &occlusion_tracker);
EXPECT_EQ(1u, queue.FullUploadSize());
EXPECT_EQ(0u, queue.PartialUploadSize());
// PrioritizedResourceManager clearing
layer_tree_host_->contents_texture_manager()->UnregisterTexture(
params.texture);
EXPECT_EQ(NULL, params.texture->resource_manager());
test_layer->SavePaintProperties();
test_layer->SetTexturePriorities(calculator);
ResourceUpdateQueue queue2;
test_layer->Update(&queue2, &occlusion_tracker);
EXPECT_EQ(1u, queue2.FullUploadSize());
EXPECT_EQ(0u, queue2.PartialUploadSize());
params = queue2.TakeFirstFullUpload();
EXPECT_TRUE(params.texture != NULL);
EXPECT_EQ(params.texture->resource_manager(),
layer_tree_host_->contents_texture_manager());
}
} // namespace
} // namespace cc