Merge from Chromium at DEPS revision 33.0.1750.22
This commit was generated by merge_to_master.py.
Change-Id: I6921ac363bb1e55bc9e48d25552106ad8d723ca7
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index a738672..4b72924 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -25,6 +25,7 @@
#include "net/cookies/cookie_store.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/http/http_cache.h"
+#include "net/http/http_stream_factory.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
@@ -196,6 +197,7 @@
}
PopulateNetworkSessionParams(url_request_context_.get(),
&network_session_params);
+
net::HttpCache* main_cache = new net::HttpCache(
network_session_params,
new net::HttpCache::DefaultBackend(
@@ -210,6 +212,10 @@
job_factory_ = CreateJobFactory(&protocol_handlers_);
url_request_context_->set_job_factory(job_factory_.get());
+
+ // TODO(sgurun) remove once crbug.com/329681 is fixed. Should be
+ // called only once.
+ net::HttpStreamFactory::EnableNpnSpdy31();
}
net::URLRequestContext* AwURLRequestContextGetter::GetURLRequestContext() {
diff --git a/ash/wm/window_manager_unittest.cc b/ash/wm/window_manager_unittest.cc
index af21613..2b97e52 100644
--- a/ash/wm/window_manager_unittest.cc
+++ b/ash/wm/window_manager_unittest.cc
@@ -704,10 +704,10 @@
env_filter->RemoveHandler(f2.get());
}
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
+// A keypress and/or touch only hides the cursor on ChromeOS (crbug.com/304296).
+#if defined(OS_CHROMEOS)
// We should show and hide the cursor in response to mouse and touch events as
-// requested. ChromeOS and Windows are the only platforms which hide the cursor
-// in response to touch (crbug.com/322250).
+// requested.
TEST_F(WindowManagerTest, UpdateCursorVisibility) {
aura::test::EventGenerator& generator = GetEventGenerator();
views::corewm::CursorManager* cursor_manager =
@@ -726,11 +726,7 @@
EXPECT_TRUE(cursor_manager->IsCursorVisible());
EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
}
-#endif // defined(OS_CHROMEOS) || defined(OS_WIN)
-#if defined(OS_CHROMEOS)
-// ChromeOS is the only platform for which the cursor is hidden on both
-// touch and keypress (crbug.com/304296).
TEST_F(WindowManagerTest, UpdateCursorVisibilityOnKeyEvent) {
aura::test::EventGenerator& generator = GetEventGenerator();
views::corewm::CursorManager* cursor_manager =
@@ -814,6 +810,6 @@
EXPECT_FALSE(observer_b.did_visibility_change());
EXPECT_TRUE(observer_a.is_cursor_visible());
}
-#endif // defined(OS_CHROMEOS)
+#endif
} // namespace ash
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 0ec6f9a..59f25e2 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -17,10 +17,6 @@
using base::android::ScopedJavaLocalRef;
JavaVM* g_jvm = NULL;
-
-// NOTE: This variable is only used for debugging http://crbug.com/322200
-const JNIInvokeInterface* g_jvm_functions = NULL;
-
// Leak the global app context, as it is used from a non-joinable worker thread
// that may still be running at shutdown. There is no harm in doing this.
base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
@@ -80,10 +76,7 @@
JNIEnv* AttachCurrentThread() {
DCHECK(g_jvm);
JNIEnv* env = NULL;
- // See http://crbug.com/322200 for the reasons for these CHECKs.
- CHECK(g_jvm);
- CHECK_EQ(g_jvm_functions, g_jvm->functions);
- jint ret = g_jvm_functions->AttachCurrentThread(g_jvm, &env, NULL);
+ jint ret = g_jvm->AttachCurrentThread(&env, NULL);
DCHECK_EQ(JNI_OK, ret);
return env;
}
@@ -91,18 +84,13 @@
void DetachFromVM() {
// Ignore the return value, if the thread is not attached, DetachCurrentThread
// will fail. But it is ok as the native thread may never be attached.
- if (g_jvm) {
- // See http://crbug.com/322200 for the reasons for these CHECKs.
- CHECK(g_jvm);
- CHECK_EQ(g_jvm_functions, g_jvm->functions);
+ if (g_jvm)
g_jvm->DetachCurrentThread();
- }
}
void InitVM(JavaVM* vm) {
DCHECK(!g_jvm);
g_jvm = vm;
- g_jvm_functions = vm->functions;
}
bool IsVMInitialized() {
diff --git a/base/process/memory_mac.mm b/base/process/memory_mac.mm
index d1518fa..3e281cd 100644
--- a/base/process/memory_mac.mm
+++ b/base/process/memory_mac.mm
@@ -117,10 +117,23 @@
// Out of memory is certainly not heap corruption, and not necessarily
// something for which the process should be terminated. Leave that decision
- // to the OOM killer. The EBADF case comes up because the malloc library
- // attempts to log to ASL (syslog) before calling this code, which fails
- // accessing a Unix-domain socket because of sandboxing.
- if (errno == ENOMEM || (errno == EBADF && g_unchecked_alloc.Get().Get()))
+ // to the OOM killer.
+ if (errno == ENOMEM)
+ return;
+
+ // The malloc library attempts to log to ASL (syslog) before calling this
+ // code, which fails accessing a Unix-domain socket when sandboxed. The
+ // failed socket results in writing to a -1 fd, leaving EBADF in errno. If
+ // UncheckedMalloc() is on the stack, for large allocations (15k and up) only
+ // an OOM failure leads here. Smaller allocations could also arrive here due
+ // to freelist corruption, but there is no way to distinguish that from OOM at
+ // this point.
+ //
+ // NOTE(shess): I hypothesize that EPERM case in 10.9 is the same root cause
+ // as EBADF. Unfortunately, 10.9's opensource releases don't include malloc
+ // source code at this time.
+ // <http://crbug.com/312234>
+ if ((errno == EBADF || errno == EPERM) && g_unchecked_alloc.Get().Get())
return;
// A unit test checks this error message, so it needs to be in release builds.
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
index 2e7a297..c021799 100644
--- a/build/util/LASTCHANGE
+++ b/build/util/LASTCHANGE
@@ -1 +1 @@
-LASTCHANGE=243220
+LASTCHANGE=243718
diff --git a/build/util/LASTCHANGE.blink b/build/util/LASTCHANGE.blink
index 24409f9..70a71c0 100644
--- a/build/util/LASTCHANGE.blink
+++ b/build/util/LASTCHANGE.blink
@@ -1 +1 @@
-LASTCHANGE=164524
+LASTCHANGE=164719
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 6c0e4b5..7af063d 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -382,8 +382,6 @@
'resources/texture_mailbox_deleter.h',
'resources/tile.cc',
'resources/tile.h',
- 'resources/tile_bundle.cc',
- 'resources/tile_bundle.h',
'resources/tile_manager.cc',
'resources/tile_manager.h',
'resources/tile_priority.cc',
diff --git a/cc/cc.target.darwin-arm.mk b/cc/cc.target.darwin-arm.mk
index 66ac98a..f1f676d 100644
--- a/cc/cc.target.darwin-arm.mk
+++ b/cc/cc.target.darwin-arm.mk
@@ -190,7 +190,6 @@
cc/resources/texture_mailbox.cc \
cc/resources/texture_mailbox_deleter.cc \
cc/resources/tile.cc \
- cc/resources/tile_bundle.cc \
cc/resources/tile_manager.cc \
cc/resources/tile_priority.cc \
cc/resources/transferable_resource.cc \
diff --git a/cc/cc.target.darwin-mips.mk b/cc/cc.target.darwin-mips.mk
index 320267f..f97efc9 100644
--- a/cc/cc.target.darwin-mips.mk
+++ b/cc/cc.target.darwin-mips.mk
@@ -190,7 +190,6 @@
cc/resources/texture_mailbox.cc \
cc/resources/texture_mailbox_deleter.cc \
cc/resources/tile.cc \
- cc/resources/tile_bundle.cc \
cc/resources/tile_manager.cc \
cc/resources/tile_priority.cc \
cc/resources/transferable_resource.cc \
diff --git a/cc/cc.target.darwin-x86.mk b/cc/cc.target.darwin-x86.mk
index 26fff27..ab3893c 100644
--- a/cc/cc.target.darwin-x86.mk
+++ b/cc/cc.target.darwin-x86.mk
@@ -190,7 +190,6 @@
cc/resources/texture_mailbox.cc \
cc/resources/texture_mailbox_deleter.cc \
cc/resources/tile.cc \
- cc/resources/tile_bundle.cc \
cc/resources/tile_manager.cc \
cc/resources/tile_priority.cc \
cc/resources/transferable_resource.cc \
diff --git a/cc/cc.target.linux-arm.mk b/cc/cc.target.linux-arm.mk
index 66ac98a..f1f676d 100644
--- a/cc/cc.target.linux-arm.mk
+++ b/cc/cc.target.linux-arm.mk
@@ -190,7 +190,6 @@
cc/resources/texture_mailbox.cc \
cc/resources/texture_mailbox_deleter.cc \
cc/resources/tile.cc \
- cc/resources/tile_bundle.cc \
cc/resources/tile_manager.cc \
cc/resources/tile_priority.cc \
cc/resources/transferable_resource.cc \
diff --git a/cc/cc.target.linux-mips.mk b/cc/cc.target.linux-mips.mk
index 320267f..f97efc9 100644
--- a/cc/cc.target.linux-mips.mk
+++ b/cc/cc.target.linux-mips.mk
@@ -190,7 +190,6 @@
cc/resources/texture_mailbox.cc \
cc/resources/texture_mailbox_deleter.cc \
cc/resources/tile.cc \
- cc/resources/tile_bundle.cc \
cc/resources/tile_manager.cc \
cc/resources/tile_priority.cc \
cc/resources/transferable_resource.cc \
diff --git a/cc/cc.target.linux-x86.mk b/cc/cc.target.linux-x86.mk
index 26fff27..ab3893c 100644
--- a/cc/cc.target.linux-x86.mk
+++ b/cc/cc.target.linux-x86.mk
@@ -190,7 +190,6 @@
cc/resources/texture_mailbox.cc \
cc/resources/texture_mailbox_deleter.cc \
cc/resources/tile.cc \
- cc/resources/tile_bundle.cc \
cc/resources/tile_manager.cc \
cc/resources/tile_priority.cc \
cc/resources/transferable_resource.cc \
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index 4ef05e8..4974ad3 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -68,7 +68,6 @@
'resources/resource_update_controller_unittest.cc',
'resources/scoped_resource_unittest.cc',
'resources/texture_mailbox_deleter_unittest.cc',
- 'resources/tile_bundle_unittest.cc',
'resources/tile_manager_unittest.cc',
'resources/tile_priority_unittest.cc',
'resources/video_resource_updater_unittest.cc',
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc
index af61bed..2910da1 100644
--- a/cc/layers/picture_image_layer_impl_unittest.cc
+++ b/cc/layers/picture_image_layer_impl_unittest.cc
@@ -10,8 +10,6 @@
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
-#include "cc/test/fake_tile_manager.h"
-#include "cc/test/fake_tile_manager_client.h"
#include "cc/test/impl_side_painting_settings.h"
#include "cc/test/mock_quad_culler.h"
#include "cc/trees/layer_tree_impl.h"
@@ -34,9 +32,7 @@
class PictureImageLayerImplTest : public testing::Test {
public:
PictureImageLayerImplTest()
- : host_impl_(ImplSidePaintingSettings(), &proxy_),
- tile_manager_(&tile_manager_client_),
- tiling_client_(&tile_manager_) {
+ : host_impl_(ImplSidePaintingSettings(), &proxy_) {
tiling_client_.SetTileSize(ImplSidePaintingSettings().default_tile_size);
host_impl_.CreatePendingTree();
host_impl_.InitializeRenderer(CreateFakeOutputSurface());
@@ -72,8 +68,6 @@
protected:
FakeImplProxy proxy_;
FakeLayerTreeHostImpl host_impl_;
- FakeTileManagerClient tile_manager_client_;
- FakeTileManager tile_manager_;
FakePictureLayerTilingClient tiling_client_;
};
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 666b72d..c4dd1f1 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -173,10 +173,10 @@
} else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
color = DebugColors::PictureTileBorderColor();
width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
- } else if (iter.priority().resolution == HIGH_RESOLUTION) {
+ } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
color = DebugColors::HighResTileBorderColor();
width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
- } else if (iter.priority().resolution == LOW_RESOLUTION) {
+ } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
color = DebugColors::LowResTileBorderColor();
width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
} else if (iter->contents_scale() > contents_scale_x()) {
@@ -484,14 +484,6 @@
flags);
}
-scoped_refptr<TileBundle> PictureLayerImpl::CreateTileBundle(int offset_x,
- int offset_y,
- int width,
- int height) {
- return layer_tree_impl()->tile_manager()->CreateTileBundle(
- offset_x, offset_y, width, height);
-}
-
void PictureLayerImpl::UpdatePile(Tile* tile) {
tile->set_picture_pile(pile_);
}
@@ -725,7 +717,7 @@
// This iteration is over the visible content rect which is potentially
// less conservative than projecting the viewport into the layer.
// Ignore tiles that are know to be outside the viewport.
- if (iter.priority().distance_to_visible_in_pixels != 0)
+ if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
continue;
missing_region.Subtract(iter.geometry_rect());
@@ -794,7 +786,7 @@
// This iteration is over the visible content rect which is potentially
// less conservative than projecting the viewport into the layer.
// Ignore tiles that are know to be outside the viewport.
- if (iter.priority().distance_to_visible_in_pixels != 0)
+ if (tile->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
continue;
// If the missing region doesn't cover it, this tile is fully
@@ -806,8 +798,7 @@
// that it is outside the visible tile rect) or this tile is shared between
// with the twin, then this tile isn't required to prevent flashing.
if (optional_twin_tiling) {
- Tile* twin_tile =
- optional_twin_tiling->TileAt(ACTIVE_TREE, iter.i(), iter.j());
+ Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j());
if (!twin_tile || twin_tile == tile) {
twin_had_missing_tile = true;
continue;
@@ -1015,8 +1006,8 @@
raster_source_scale_ = ideal_source_scale_;
bool is_pinching = layer_tree_impl()->PinchGestureActive();
- if (!is_pinching) {
- // When not pinching, we use ideal scale:
+ if (!is_pinching || raster_contents_scale_ == 0.f) {
+ // When not pinching or when we have no previous scale, we use ideal scale:
raster_page_scale_ = ideal_page_scale_;
raster_contents_scale_ = ideal_contents_scale_;
} else {
@@ -1031,6 +1022,9 @@
raster_page_scale_ = raster_contents_scale_ / raster_device_scale_;
}
+ raster_contents_scale_ =
+ std::max(raster_contents_scale_, MinimumContentsScale());
+
// Don't allow animating CSS scales to drop below 1. This is needed because
// changes in raster source scale aren't handled. See the comment in
// ShouldAdjustRasterScale.
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index 10d3f6d..ab6aad7 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -55,10 +55,6 @@
// PictureLayerTilingClient overrides.
virtual scoped_refptr<Tile> CreateTile(PictureLayerTiling* tiling,
gfx::Rect content_rect) OVERRIDE;
- virtual scoped_refptr<TileBundle> CreateTileBundle(int offset_x,
- int offset_y,
- int width,
- int height) OVERRIDE;
virtual void UpdatePile(Tile* tile) OVERRIDE;
virtual gfx::Size CalculateTileSize(
gfx::Size content_bounds) const OVERRIDE;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index d4b0280..553080a 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -93,9 +93,9 @@
void CreateHighLowResAndSetAllTilesVisible() {
// Active layer must get updated first so pending layer can share from it.
- active_layer_->CreateDefaultTilingsAndTiles(ACTIVE_TREE);
+ active_layer_->CreateDefaultTilingsAndTiles();
active_layer_->SetAllTilesVisible();
- pending_layer_->CreateDefaultTilingsAndTiles(PENDING_TREE);
+ pending_layer_->CreateDefaultTilingsAndTiles();
pending_layer_->SetAllTilesVisible();
}
@@ -103,16 +103,11 @@
active_layer_->AddTiling(2.3f);
active_layer_->AddTiling(1.0f);
active_layer_->AddTiling(0.5f);
- for (size_t i = 0; i < active_layer_->tilings()->num_tilings(); ++i) {
- active_layer_->tilings()->tiling_at(i)->CreateTilesForTesting(
- ACTIVE_TREE);
- }
+ for (size_t i = 0; i < active_layer_->tilings()->num_tilings(); ++i)
+ active_layer_->tilings()->tiling_at(i)->CreateAllTilesForTesting();
pending_layer_->set_invalidation(invalidation);
- for (size_t i = 0; i < pending_layer_->tilings()->num_tilings(); ++i) {
- pending_layer_->tilings()
- ->tiling_at(i)
- ->CreateTilesForTesting(PENDING_TREE);
- }
+ for (size_t i = 0; i < pending_layer_->tilings()->num_tilings(); ++i)
+ pending_layer_->tilings()->tiling_at(i)->CreateAllTilesForTesting();
}
void SetupPendingTree(
@@ -174,14 +169,14 @@
}
void AssertAllTilesRequired(PictureLayerTiling* tiling) {
- std::vector<Tile*> tiles = tiling->TilesForTesting(PENDING_TREE);
+ std::vector<Tile*> tiles = tiling->AllTilesForTesting();
for (size_t i = 0; i < tiles.size(); ++i)
EXPECT_TRUE(tiles[i]->required_for_activation()) << "i: " << i;
EXPECT_GT(tiles.size(), 0u);
}
void AssertNoTilesRequired(PictureLayerTiling* tiling) {
- std::vector<Tile*> tiles = tiling->TilesForTesting(PENDING_TREE);
+ std::vector<Tile*> tiles = tiling->AllTilesForTesting();
for (size_t i = 0; i < tiles.size(); ++i)
EXPECT_FALSE(tiles[i]->required_for_activation()) << "i: " << i;
EXPECT_GT(tiles.size(), 0u);
@@ -1222,6 +1217,7 @@
++iter) {
if (!*iter)
continue;
+ Tile* tile = *iter;
TilePriority priority;
priority.resolution = HIGH_RESOLUTION;
if (++tile_count % 2) {
@@ -1231,7 +1227,7 @@
priority.time_to_visible_in_seconds = 1.f;
priority.distance_to_visible_in_pixels = 1.f;
}
- iter.SetPriorityForTesting(priority);
+ tile->SetPriority(PENDING_TREE, priority);
}
pending_layer_->MarkVisibleResourcesAsRequired();
@@ -1248,7 +1244,7 @@
if (!*iter)
continue;
const Tile* tile = *iter;
- if (iter.priority().distance_to_visible_in_pixels == 0.f) {
+ if (tile->priority(PENDING_TREE).distance_to_visible_in_pixels == 0.f) {
EXPECT_TRUE(tile->required_for_activation());
num_visible++;
} else {
@@ -1319,8 +1315,7 @@
// Active layer has tilings, but no tiles due to missing recordings.
EXPECT_TRUE(active_layer_->CanHaveTilings());
EXPECT_EQ(active_layer_->tilings()->num_tilings(), 2u);
- EXPECT_EQ(active_layer_->HighResTiling()->TilesForTesting(ACTIVE_TREE).size(),
- 0u);
+ EXPECT_EQ(active_layer_->HighResTiling()->AllTilesForTesting().size(), 0u);
// Since the active layer has no tiles at all, the pending layer doesn't
// need content in order to activate. This is attempting to simulate
@@ -1425,6 +1420,53 @@
EXPECT_EQ(0u, active_layer_->num_tilings());
}
+TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) {
+ SetupDefaultTrees(gfx::Size(10, 10));
+ host_impl_.PinchGestureBegin();
+ float high_res_scale = 2.3f;
+ SetContentsScaleOnBothLayers(high_res_scale, 1.f, 1.f, false);
+
+ ASSERT_GE(pending_layer_->num_tilings(), 0u);
+ EXPECT_FLOAT_EQ(high_res_scale,
+ pending_layer_->HighResTiling()->contents_scale());
+}
+
+TEST_F(PictureLayerImplTest, FirstTilingTooSmall) {
+ SetupDefaultTrees(gfx::Size(10, 10));
+ host_impl_.PinchGestureBegin();
+ float high_res_scale = 0.0001f;
+ EXPECT_GT(pending_layer_->MinimumContentsScale(), high_res_scale);
+
+ SetContentsScaleOnBothLayers(high_res_scale, 1.f, 1.f, false);
+
+ ASSERT_GE(pending_layer_->num_tilings(), 0u);
+ EXPECT_FLOAT_EQ(pending_layer_->MinimumContentsScale(),
+ pending_layer_->HighResTiling()->contents_scale());
+}
+
+TEST_F(PictureLayerImplTest, PinchingTooSmall) {
+ SetupDefaultTrees(gfx::Size(10, 10));
+
+ float contents_scale = 0.15f;
+ SetContentsScaleOnBothLayers(contents_scale, 1.f, 1.f, false);
+
+ ASSERT_GE(pending_layer_->num_tilings(), 0u);
+ EXPECT_FLOAT_EQ(contents_scale,
+ pending_layer_->HighResTiling()->contents_scale());
+
+ host_impl_.PinchGestureBegin();
+
+ float page_scale = 0.0001f;
+ EXPECT_LT(page_scale * contents_scale,
+ pending_layer_->MinimumContentsScale());
+
+
+ SetContentsScaleOnBothLayers(contents_scale, 1.f, page_scale, false);
+ ASSERT_GE(pending_layer_->num_tilings(), 0u);
+ EXPECT_FLOAT_EQ(pending_layer_->MinimumContentsScale(),
+ pending_layer_->HighResTiling()->contents_scale());
+}
+
class DeferredInitPictureLayerImplTest : public PictureLayerImplTest {
public:
DeferredInitPictureLayerImplTest()
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 6802e55..1aa3567 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -17,29 +17,6 @@
namespace cc {
-namespace {
-
-const int kTileBundleWidth = 2;
-const int kTileBundleHeight = 2;
-
-std::pair<int, int> ComputeTileBundleIndex(int i, int j) {
- return std::make_pair(i / kTileBundleWidth, j / kTileBundleHeight);
-}
-
-gfx::Size ComputeBundleTextureSize(gfx::Size tile_size,
- const TilingData& tiling_data) {
- int border_texels = tiling_data.border_texels();
-
- int inner_tile_width = tile_size.width() - 2 * border_texels;
- int bundle_width = inner_tile_width * kTileBundleWidth + 2 * border_texels;
-
- int inner_tile_height = tile_size.height() - 2 * border_texels;
- int bundle_height = inner_tile_height * kTileBundleHeight + 2 * border_texels;
- return gfx::Size(bundle_width, bundle_height);
-}
-
-} // namespace
-
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
float contents_scale,
gfx::Size layer_bounds,
@@ -57,8 +34,6 @@
resolution_(NON_IDEAL_RESOLUTION),
client_(client),
tiling_data_(gfx::Size(), gfx::Size(), true),
- bundle_tiling_data_(gfx::Size(), gfx::Size(), true),
- current_tree_(PENDING_TREE),
last_impl_frame_time_in_seconds_(0.0) {
gfx::Size content_bounds =
gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale));
@@ -72,13 +47,9 @@
tiling_data_.SetTotalSize(content_bounds);
tiling_data_.SetMaxTextureSize(tile_size);
- bundle_tiling_data_.SetTotalSize(content_bounds);
- bundle_tiling_data_.SetMaxTextureSize(
- ComputeBundleTextureSize(tile_size, tiling_data_));
}
PictureLayerTiling::~PictureLayerTiling() {
- SetLiveTilesRect(gfx::Rect());
}
void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) {
@@ -93,103 +64,41 @@
return gfx::ScaleSize(layer_bounds_, contents_scale_);
}
-TileBundle* PictureLayerTiling::CreateBundleForTileAt(
- int i,
- int j,
- const PictureLayerTiling* twin_tiling) {
- TileBundleMapKey key = ComputeTileBundleIndex(i, j);
- DCHECK(tile_bundles_.find(key) == tile_bundles_.end());
-
- scoped_refptr<TileBundle> candidate_bundle = NULL;
-
- // Always try to get the twin bundle first. TileBundles are always shared
- // between trees.
- if (twin_tiling &&
- tiling_data_.max_texture_size() ==
- twin_tiling->tiling_data_.max_texture_size()) {
- candidate_bundle = twin_tiling->TileBundleAt(key.first, key.second);
- }
-
- // If we couldn't get a tile bundle, create a new one.
- if (!candidate_bundle) {
- candidate_bundle = client_->CreateTileBundle(key.first * kTileBundleWidth,
- key.second * kTileBundleHeight,
- kTileBundleWidth,
- kTileBundleHeight);
- }
- candidate_bundle->SwapTilesIfRequired();
- tile_bundles_[key] = candidate_bundle;
- return candidate_bundle.get();
-}
-
-TileBundle* PictureLayerTiling::TileBundleContainingTileAt(int i, int j) const {
- TileBundleMapKey key = ComputeTileBundleIndex(i, j);
- return TileBundleAt(key.first, key.second);
-}
-
-TileBundle* PictureLayerTiling::TileBundleAt(int i, int j) const {
- TileBundleMapKey key(i, j);
- TileBundleMap::const_iterator it = tile_bundles_.find(key);
- if (it == tile_bundles_.end())
+Tile* PictureLayerTiling::TileAt(int i, int j) const {
+ TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j));
+ if (iter == tiles_.end())
return NULL;
- it->second->SwapTilesIfRequired();
- return it->second.get();
+ return iter->second.get();
}
-Tile* PictureLayerTiling::TileAt(WhichTree tree, int i, int j) const {
- TileBundle* bundle = TileBundleContainingTileAt(i, j);
- if (!bundle)
- return NULL;
- return bundle->TileAt(tree, i, j);
-}
-
-void PictureLayerTiling::CreateTile(WhichTree tree,
- int i,
+void PictureLayerTiling::CreateTile(int i,
int j,
const PictureLayerTiling* twin_tiling) {
- TileBundle* bundle = TileBundleContainingTileAt(i, j);
- if (!bundle)
- bundle = CreateBundleForTileAt(i, j, twin_tiling);
+ TileMapKey key(i, j);
+ DCHECK(tiles_.find(key) == tiles_.end());
gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j);
gfx::Rect tile_rect = paint_rect;
tile_rect.set_size(tiling_data_.max_texture_size());
// Check our twin for a valid tile.
- WhichTree twin_tree = (tree == ACTIVE_TREE) ? PENDING_TREE : ACTIVE_TREE;
- if (Tile* candidate_tile = bundle->TileAt(twin_tree, i, j)) {
- gfx::Rect rect =
- gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_);
- if (!client_->GetInvalidation()->Intersects(rect)) {
- bundle->AddTileAt(tree, i, j, candidate_tile);
- return;
+ if (twin_tiling &&
+ tiling_data_.max_texture_size() ==
+ twin_tiling->tiling_data_.max_texture_size()) {
+ if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) {
+ gfx::Rect rect =
+ gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_);
+ if (!client_->GetInvalidation()->Intersects(rect)) {
+ tiles_[key] = candidate_tile;
+ return;
+ }
}
}
// Create a new tile because our twin didn't have a valid one.
scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
if (tile.get())
- bundle->AddTileAt(tree, i, j, tile);
-}
-
-bool PictureLayerTiling::RemoveTile(WhichTree tree, int i, int j) {
- TileBundleMapKey key = ComputeTileBundleIndex(i, j);
- TileBundleMap::iterator it = tile_bundles_.find(key);
- if (it == tile_bundles_.end())
- return false;
-
- it->second->SwapTilesIfRequired();
- return it->second->RemoveTileAt(tree, i, j);
-}
-
-void PictureLayerTiling::RemoveBundleContainingTileAtIfEmpty(int i, int j) {
- TileBundleMapKey key = ComputeTileBundleIndex(i, j);
- TileBundleMap::iterator it = tile_bundles_.find(key);
- if (it == tile_bundles_.end())
- return;
-
- if (it->second->IsEmpty())
- tile_bundles_.erase(it);
+ tiles_[key] = tile;
}
Region PictureLayerTiling::OpaqueRegionInContentRect(
@@ -200,30 +109,19 @@
}
void PictureLayerTiling::SetCanUseLCDText(bool can_use_lcd_text) {
- // TODO(vmpstr): This can be done per bundle with results used
- // in tile manager.
- for (TileBundleMap::iterator it = tile_bundles_.begin();
- it != tile_bundles_.end();
- ++it) {
- for (TileBundle::Iterator tile_it(it->second, current_tree_);
- tile_it;
- ++tile_it)
- tile_it->set_can_use_lcd_text(can_use_lcd_text);
- }
+ for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it)
+ it->second->set_can_use_lcd_text(can_use_lcd_text);
}
void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
- DCHECK(current_tree_ == PENDING_TREE);
-
const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_); iter;
++iter) {
- int tile_x = iter.index_x();
- int tile_y = iter.index_y();
- Tile* tile = TileAt(PENDING_TREE, tile_x, tile_y);
- if (tile)
+ TileMapKey key = iter.index();
+ TileMap::iterator find = tiles_.find(key);
+ if (find != tiles_.end())
continue;
- CreateTile(PENDING_TREE, tile_x, tile_y, twin_tiling);
+ CreateTile(key.first, key.second, twin_tiling);
}
}
@@ -231,7 +129,6 @@
if (layer_bounds_ == layer_bounds)
return;
- DCHECK(current_tree_ == PENDING_TREE);
DCHECK(!layer_bounds.IsEmpty());
gfx::Size old_layer_bounds = layer_bounds_;
@@ -244,9 +141,6 @@
if (tile_size != tiling_data_.max_texture_size()) {
tiling_data_.SetTotalSize(content_bounds);
tiling_data_.SetMaxTextureSize(tile_size);
- bundle_tiling_data_.SetTotalSize(content_bounds);
- bundle_tiling_data_.SetMaxTextureSize(
- ComputeBundleTextureSize(tile_size, tiling_data_));
Reset();
return;
}
@@ -256,7 +150,6 @@
bounded_live_tiles_rect.Intersect(gfx::Rect(content_bounds));
SetLiveTilesRect(bounded_live_tiles_rect);
tiling_data_.SetTotalSize(content_bounds);
- bundle_tiling_data_.SetTotalSize(content_bounds);
// Create tiles for newly exposed areas.
Region layer_region((gfx::Rect(layer_bounds_)));
@@ -265,9 +158,7 @@
}
void PictureLayerTiling::Invalidate(const Region& layer_region) {
- DCHECK(current_tree_ == PENDING_TREE);
-
- std::vector<std::pair<int, int> > new_tile_keys;
+ std::vector<TileMapKey> new_tile_keys;
for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) {
gfx::Rect layer_rect = iter.rect();
gfx::Rect content_rect =
@@ -276,23 +167,18 @@
if (content_rect.IsEmpty())
continue;
for (TilingData::Iterator iter(&tiling_data_, content_rect); iter; ++iter) {
- int tile_x = iter.index_x();
- int tile_y = iter.index_y();
-
- // If there is no bundle for the given tile, we can skip.
- bool deleted = RemoveTile(PENDING_TREE, tile_x, tile_y);
- if (deleted)
- new_tile_keys.push_back(std::make_pair(tile_x, tile_y));
+ TileMapKey key(iter.index());
+ TileMap::iterator find = tiles_.find(key);
+ if (find == tiles_.end())
+ continue;
+ tiles_.erase(find);
+ new_tile_keys.push_back(key);
}
}
const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
- for (size_t i = 0; i < new_tile_keys.size(); ++i) {
- CreateTile(PENDING_TREE,
- new_tile_keys[i].first,
- new_tile_keys[i].second,
- twin_tiling);
- }
+ for (size_t i = 0; i < new_tile_keys.size(); ++i)
+ CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, twin_tiling);
}
PictureLayerTiling::CoverageIterator::CoverageIterator()
@@ -319,8 +205,7 @@
left_(0),
top_(0),
right_(-1),
- bottom_(-1),
- tree_(tiling->current_tree_) {
+ bottom_(-1) {
DCHECK(tiling_);
if (dest_rect_.IsEmpty())
return;
@@ -375,7 +260,7 @@
}
}
- current_tile_ = tiling_->TileAt(tree_, tile_i_, tile_j_);
+ current_tile_ = tiling_->TileAt(tile_i_, tile_j_);
// Calculate the current geometry rect. Due to floating point rounding
// and ToEnclosingRect, tiles might overlap in destination space on the
@@ -431,19 +316,6 @@
return rect;
}
-TilePriority PictureLayerTiling::CoverageIterator::priority() {
- TileBundle* bundle = tiling_->TileBundleContainingTileAt(tile_i_, tile_j_);
- if (bundle)
- return bundle->GetPriority(tree_);
- return TilePriority();
-}
-
-void PictureLayerTiling::CoverageIterator::SetPriorityForTesting(
- const TilePriority& priority) {
- TileBundle* bundle = tiling_->TileBundleContainingTileAt(tile_i_, tile_j_);
- bundle->SetPriority(tree_, priority);
-}
-
gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const {
gfx::PointF tex_origin =
tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin();
@@ -464,7 +336,7 @@
void PictureLayerTiling::Reset() {
live_tiles_rect_ = gfx::Rect();
- tile_bundles_.clear();
+ tiles_.clear();
}
void PictureLayerTiling::UpdateTilePriorities(
@@ -480,10 +352,6 @@
const gfx::Transform& current_screen_transform,
double current_frame_time_in_seconds,
size_t max_tiles_for_interest_area) {
- if (!has_ever_been_updated())
- current_tree_ = tree;
-
- DCHECK_EQ(tree, current_tree_);
if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
// This should never be zero for the purposes of has_ever_been_updated().
DCHECK_NE(current_frame_time_in_seconds, 0.0);
@@ -539,22 +407,23 @@
last_screen_transform.matrix().get(0, 3),
last_screen_transform.matrix().get(1, 3));
- for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect);
+ for (TilingData::Iterator iter(&tiling_data_, interest_rect);
iter; ++iter) {
- int bundle_x = iter.index_x();
- int bundle_y = iter.index_y();
- TileBundle* bundle = TileBundleAt(bundle_x, bundle_y);
- if (!bundle)
+ TileMap::iterator find = tiles_.find(iter.index());
+ if (find == tiles_.end())
continue;
+ Tile* tile = find->second.get();
- gfx::Rect bundle_bounds =
- bundle_tiling_data_.TileBounds(bundle_x, bundle_y);
- gfx::RectF current_screen_rect =
- gfx::ScaleRect(bundle_bounds, current_scale, current_scale) +
- current_offset;
- gfx::RectF last_screen_rect =
- gfx::ScaleRect(bundle_bounds, last_scale, last_scale) +
- last_offset;
+ gfx::Rect tile_bounds =
+ tiling_data_.TileBounds(iter.index_x(), iter.index_y());
+ gfx::RectF current_screen_rect = gfx::ScaleRect(
+ tile_bounds,
+ current_scale,
+ current_scale) + current_offset;
+ gfx::RectF last_screen_rect = gfx::ScaleRect(
+ tile_bounds,
+ last_scale,
+ last_scale) + last_offset;
float distance_to_visible_in_pixels =
current_screen_rect.ManhattanInternalDistance(view_rect);
@@ -566,8 +435,7 @@
resolution_,
time_to_visible_in_seconds,
distance_to_visible_in_pixels);
-
- bundle->SetPriority(tree, priority);
+ tile->SetPriority(tree, priority);
}
} else if (!last_screen_transform.HasPerspective() &&
!current_screen_transform.HasPerspective()) {
@@ -587,57 +455,55 @@
last_screen_transform.matrix().get(0, 3),
last_screen_transform.matrix().get(1, 3));
- float current_bundle_width =
- bundle_tiling_data_.TileSizeX(0) * current_scale;
- float last_bundle_width =
- bundle_tiling_data_.TileSizeX(0) * last_scale;
- float current_bundle_height =
- bundle_tiling_data_.TileSizeY(0) * current_scale;
- float last_bundle_height =
- bundle_tiling_data_.TileSizeY(0) * last_scale;
+ float current_tile_width = tiling_data_.TileSizeX(0) * current_scale;
+ float last_tile_width = tiling_data_.TileSizeX(0) * last_scale;
+ float current_tile_height = tiling_data_.TileSizeY(0) * current_scale;
+ float last_tile_height = tiling_data_.TileSizeY(0) * last_scale;
// Apply screen space transform to local basis vectors (tile_width, 0) and
// (0, tile_height); the math simplifies and can be initialized directly.
gfx::Vector2dF current_horizontal(
- current_screen_transform.matrix().get(0, 0) * current_bundle_width,
- current_screen_transform.matrix().get(1, 0) * current_bundle_width);
+ current_screen_transform.matrix().get(0, 0) * current_tile_width,
+ current_screen_transform.matrix().get(1, 0) * current_tile_width);
gfx::Vector2dF current_vertical(
- current_screen_transform.matrix().get(0, 1) * current_bundle_height,
- current_screen_transform.matrix().get(1, 1) * current_bundle_height);
+ current_screen_transform.matrix().get(0, 1) * current_tile_height,
+ current_screen_transform.matrix().get(1, 1) * current_tile_height);
gfx::Vector2dF last_horizontal(
- last_screen_transform.matrix().get(0, 0) * last_bundle_width,
- last_screen_transform.matrix().get(1, 0) * last_bundle_width);
+ last_screen_transform.matrix().get(0, 0) * last_tile_width,
+ last_screen_transform.matrix().get(1, 0) * last_tile_width);
gfx::Vector2dF last_vertical(
- last_screen_transform.matrix().get(0, 1) * last_bundle_height,
- last_screen_transform.matrix().get(1, 1) * last_bundle_height);
+ last_screen_transform.matrix().get(0, 1) * last_tile_height,
+ last_screen_transform.matrix().get(1, 1) * last_tile_height);
- for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect);
+ for (TilingData::Iterator iter(&tiling_data_, interest_rect);
iter; ++iter) {
- int bundle_x = iter.index_x();
- int bundle_y = iter.index_y();
- TileBundle* bundle = TileBundleAt(bundle_x, bundle_y);
- if (!bundle)
+ TileMap::iterator find = tiles_.find(iter.index());
+ if (find == tiles_.end())
continue;
- gfx::PointF current_bundle_origin = current_screen_space_origin +
- ScaleVector2d(current_horizontal, bundle_x) +
- ScaleVector2d(current_vertical, bundle_y);
- gfx::PointF last_bundle_origin = last_screen_space_origin +
- ScaleVector2d(last_horizontal, bundle_x) +
- ScaleVector2d(last_vertical, bundle_y);
+ Tile* tile = find->second.get();
+
+ int i = iter.index_x();
+ int j = iter.index_y();
+ gfx::PointF current_tile_origin = current_screen_space_origin +
+ ScaleVector2d(current_horizontal, i) +
+ ScaleVector2d(current_vertical, j);
+ gfx::PointF last_tile_origin = last_screen_space_origin +
+ ScaleVector2d(last_horizontal, i) +
+ ScaleVector2d(last_vertical, j);
gfx::RectF current_screen_rect = gfx::QuadF(
- current_bundle_origin,
- current_bundle_origin + current_horizontal,
- current_bundle_origin + current_horizontal + current_vertical,
- current_bundle_origin + current_vertical).BoundingBox();
+ current_tile_origin,
+ current_tile_origin + current_horizontal,
+ current_tile_origin + current_horizontal + current_vertical,
+ current_tile_origin + current_vertical).BoundingBox();
gfx::RectF last_screen_rect = gfx::QuadF(
- last_bundle_origin,
- last_bundle_origin + last_horizontal,
- last_bundle_origin + last_horizontal + last_vertical,
- last_bundle_origin + last_vertical).BoundingBox();
+ last_tile_origin,
+ last_tile_origin + last_horizontal,
+ last_tile_origin + last_horizontal + last_vertical,
+ last_tile_origin + last_vertical).BoundingBox();
float distance_to_visible_in_pixels =
current_screen_rect.ManhattanInternalDistance(view_rect);
@@ -649,28 +515,26 @@
resolution_,
time_to_visible_in_seconds,
distance_to_visible_in_pixels);
-
- bundle->SetPriority(tree, priority);
+ tile->SetPriority(tree, priority);
}
} else {
- for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect);
+ for (TilingData::Iterator iter(&tiling_data_, interest_rect);
iter; ++iter) {
- int bundle_x = iter.index_x();
- int bundle_y = iter.index_y();
- TileBundle* bundle = TileBundleAt(bundle_x, bundle_y);
- if (!bundle)
+ TileMap::iterator find = tiles_.find(iter.index());
+ if (find == tiles_.end())
continue;
+ Tile* tile = find->second.get();
- gfx::Rect bundle_bounds =
- bundle_tiling_data_.TileBounds(bundle_x, bundle_y);
+ gfx::Rect tile_bounds =
+ tiling_data_.TileBounds(iter.index_x(), iter.index_y());
gfx::RectF current_layer_content_rect = gfx::ScaleRect(
- bundle_bounds,
+ tile_bounds,
current_scale,
current_scale);
gfx::RectF current_screen_rect = MathUtil::MapClippedRect(
current_screen_transform, current_layer_content_rect);
gfx::RectF last_layer_content_rect = gfx::ScaleRect(
- bundle_bounds,
+ tile_bounds,
last_scale,
last_scale);
gfx::RectF last_screen_rect = MathUtil::MapClippedRect(
@@ -687,15 +551,15 @@
resolution_,
time_to_visible_in_seconds,
distance_to_visible_in_pixels);
-
- bundle->SetPriority(tree, priority);
+ tile->SetPriority(tree, priority);
}
}
last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
}
-void PictureLayerTiling::SetLiveTilesRect(gfx::Rect new_live_tiles_rect) {
+void PictureLayerTiling::SetLiveTilesRect(
+ gfx::Rect new_live_tiles_rect) {
DCHECK(new_live_tiles_rect.IsEmpty() ||
ContentRect().Contains(new_live_tiles_rect));
if (live_tiles_rect_ == new_live_tiles_rect)
@@ -707,18 +571,12 @@
new_live_tiles_rect);
iter;
++iter) {
- int tile_x = iter.index_x();
- int tile_y = iter.index_y();
-
+ TileMapKey key(iter.index());
+ TileMap::iterator found = tiles_.find(key);
// If the tile was outside of the recorded region, it won't exist even
// though it was in the live rect.
- RemoveTile(current_tree_, tile_x, tile_y);
- RemoveBundleContainingTileAtIfEmpty(tile_x, tile_y);
- }
-
- if (new_live_tiles_rect.IsEmpty()) {
- live_tiles_rect_ = new_live_tiles_rect;
- return;
+ if (found != tiles_.end())
+ tiles_.erase(found);
}
const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
@@ -729,7 +587,8 @@
live_tiles_rect_);
iter;
++iter) {
- CreateTile(current_tree_, iter.index_x(), iter.index_y(), twin_tiling);
+ TileMapKey key(iter.index());
+ CreateTile(key.first, key.second, twin_tiling);
}
live_tiles_rect_ = new_live_tiles_rect;
@@ -740,52 +599,35 @@
// still in the tree. Calling this first on an active tiling that is becoming
// recycled takes care of tiles that are no longer in the active tree (eg.
// due to a pending invalidation).
- for (TileBundleMap::const_iterator it = tile_bundles_.begin();
- it != tile_bundles_.end();
- ++it) {
- it->second->DidBecomeRecycled();
+ for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+ it->second->SetPriority(ACTIVE_TREE, TilePriority());
}
- // Note that recycled tree would not be accessed, and the next tree
- // stage after recycled in pending, so we can just set the state to
- // pending here.
- current_tree_ = PENDING_TREE;
}
void PictureLayerTiling::DidBecomeActive() {
- for (TileBundleMap::const_iterator it = tile_bundles_.begin();
- it != tile_bundles_.end();
- ++it) {
- it->second->DidBecomeActive();
- for (TileBundle::Iterator tile_it(it->second.get(), ACTIVE_TREE);
- tile_it;
- ++tile_it) {
- // Tile holds a ref onto a picture pile. If the tile never gets
- // invalidated and recreated, then that picture pile ref could exist
- // indefinitely. To prevent this, ask the client to update the pile to
- // its own ref. This will cause PicturePileImpls and their clones to get
- // deleted once the corresponding PictureLayerImpl and any in flight
- // raster jobs go out of scope.
- client_->UpdatePile(*tile_it);
- }
+ for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+ it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE));
+ it->second->SetPriority(PENDING_TREE, TilePriority());
+
+ // Tile holds a ref onto a picture pile. If the tile never gets invalidated
+ // and recreated, then that picture pile ref could exist indefinitely. To
+ // prevent this, ask the client to update the pile to its own ref. This
+ // will cause PicturePileImpls and their clones to get deleted once the
+ // corresponding PictureLayerImpl and any in flight raster jobs go out of
+ // scope.
+ client_->UpdatePile(it->second.get());
}
- current_tree_ = ACTIVE_TREE;
}
void PictureLayerTiling::UpdateTilesToCurrentPile() {
- for (TileBundleMap::const_iterator it = tile_bundles_.begin();
- it != tile_bundles_.end();
- ++it) {
- for (TileBundle::Iterator tile_it(it->second.get(), PENDING_TREE);
- tile_it;
- ++tile_it) {
- client_->UpdatePile(*tile_it);
- }
+ for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+ client_->UpdatePile(it->second.get());
}
}
scoped_ptr<base::Value> PictureLayerTiling::AsValue() const {
scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
- state->SetInteger("num_tile_bundles", tile_bundles_.size());
+ state->SetInteger("num_tiles", tiles_.size());
state->SetDouble("content_scale", contents_scale_);
state->Set("content_bounds",
MathUtil::AsValue(ContentRect().size()).release());
@@ -794,11 +636,9 @@
size_t PictureLayerTiling::GPUMemoryUsageInBytes() const {
size_t amount = 0;
- for (TileBundleMap::const_iterator it = tile_bundles_.begin();
- it != tile_bundles_.end();
- ++it) {
- for (TileBundle::Iterator tile_it(it->second.get()); tile_it; ++tile_it)
- amount += tile_it->GPUMemoryUsageInBytes();
+ for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+ const Tile* tile = it->second.get();
+ amount += tile->GPUMemoryUsageInBytes();
}
return amount;
}
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index 8a539a8..dae6272 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -15,7 +15,6 @@
#include "cc/base/region.h"
#include "cc/base/tiling_data.h"
#include "cc/resources/tile.h"
-#include "cc/resources/tile_bundle.h"
#include "cc/resources/tile_priority.h"
#include "ui/gfx/rect.h"
@@ -30,10 +29,6 @@
virtual scoped_refptr<Tile> CreateTile(
PictureLayerTiling* tiling,
gfx::Rect content_rect) = 0;
- virtual scoped_refptr<TileBundle> CreateTileBundle(int offset_x,
- int offset_y,
- int width,
- int height) = 0;
virtual void UpdatePile(Tile* tile) = 0;
virtual gfx::Size CalculateTileSize(
gfx::Size content_bounds) const = 0;
@@ -71,49 +66,15 @@
gfx::Size tile_size() const { return tiling_data_.max_texture_size(); }
float contents_scale() const { return contents_scale_; }
- Tile* TileAt(WhichTree tree, int, int) const;
-
- void SetTreeForTesting(WhichTree tree) {
- current_tree_ = tree;
- }
void CreateAllTilesForTesting() {
- current_tree_ = ACTIVE_TREE;
- SetLiveTilesRect(gfx::Rect(tiling_data_.total_size()));
- live_tiles_rect_ = gfx::Rect();
- current_tree_ = PENDING_TREE;
SetLiveTilesRect(gfx::Rect(tiling_data_.total_size()));
}
- void CreateTilesForTesting(WhichTree tree) {
- current_tree_ = tree;
- SetLiveTilesRect(gfx::Rect(tiling_data_.total_size()));
- }
+
std::vector<Tile*> AllTilesForTesting() const {
std::vector<Tile*> all_tiles;
- for (TileBundleMap::const_iterator it = tile_bundles_.begin();
- it != tile_bundles_.end(); ++it) {
- for (TileBundle::Iterator tile_it(it->second.get()); tile_it; ++tile_it)
- all_tiles.push_back(*tile_it);
- }
- return all_tiles;
- }
- std::vector<TileBundle*> AllTileBundlesForTesting() const {
- std::vector<TileBundle*> all_bundles;
- for (TileBundleMap::const_iterator it = tile_bundles_.begin();
- it != tile_bundles_.end(); ++it) {
- all_bundles.push_back(it->second.get());
- }
- return all_bundles;
- }
- std::vector<Tile*> TilesForTesting(WhichTree tree) const {
- std::vector<Tile*> all_tiles;
- for (TileBundleMap::const_iterator it = tile_bundles_.begin();
- it != tile_bundles_.end(); ++it) {
- for (TileBundle::Iterator tile_it(it->second.get(), tree);
- tile_it;
- ++tile_it) {
- all_tiles.push_back(*tile_it);
- }
- }
+ for (TileMap::const_iterator it = tiles_.begin();
+ it != tiles_.end(); ++it)
+ all_tiles.push_back(it->second.get());
return all_tiles;
}
@@ -145,9 +106,6 @@
Tile* operator->() const { return current_tile_; }
Tile* operator*() const { return current_tile_; }
- TilePriority priority();
- void SetPriorityForTesting(const TilePriority& priority);
-
CoverageIterator& operator++();
operator bool() const { return tile_j_ <= bottom_; }
@@ -167,7 +125,6 @@
int top_;
int right_;
int bottom_;
- WhichTree tree_;
friend class PictureLayerTiling;
};
@@ -232,28 +189,14 @@
}
protected:
- friend class CoverageIterator;
- friend class TileBundle;
-
- typedef std::pair<int, int> TileBundleMapKey;
- typedef base::hash_map<TileBundleMapKey, scoped_refptr<TileBundle> >
- TileBundleMap;
+ typedef std::pair<int, int> TileMapKey;
+ typedef base::hash_map<TileMapKey, scoped_refptr<Tile> > TileMap;
PictureLayerTiling(float contents_scale,
gfx::Size layer_bounds,
PictureLayerTilingClient* client);
void SetLiveTilesRect(gfx::Rect live_tiles_rect);
- void CreateTile(WhichTree tree,
- int i,
- int j,
- const PictureLayerTiling* twin_tiling);
- bool RemoveTile(WhichTree tree, int i, int j);
- void RemoveBundleContainingTileAtIfEmpty(int i, int j);
- TileBundle* TileBundleContainingTileAt(int, int) const;
- TileBundle* CreateBundleForTileAt(int,
- int,
- const PictureLayerTiling* twin_tiling);
- TileBundle* TileBundleAt(int, int) const;
+ void CreateTile(int i, int j, const PictureLayerTiling* twin_tiling);
// Given properties.
float contents_scale_;
@@ -263,15 +206,14 @@
// Internal data.
TilingData tiling_data_;
- TilingData bundle_tiling_data_;
- // It is not legal to have a NULL tile bundle in the tile_bundles_ map.
- TileBundleMap tile_bundles_;
+ TileMap tiles_; // It is not legal to have a NULL tile in the tiles_ map.
gfx::Rect live_tiles_rect_;
- WhichTree current_tree_;
// State saved for computing velocities based upon finite differences.
double last_impl_frame_time_in_seconds_;
+ friend class CoverageIterator;
+
private:
DISALLOW_ASSIGN(PictureLayerTiling);
diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc
index c981a0a..7a9b8df 100644
--- a/cc/resources/picture_layer_tiling_perftest.cc
+++ b/cc/resources/picture_layer_tiling_perftest.cc
@@ -4,8 +4,6 @@
#include "cc/resources/picture_layer_tiling.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
-#include "cc/test/fake_tile_manager.h"
-#include "cc/test/fake_tile_manager_client.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
@@ -20,17 +18,13 @@
class PictureLayerTilingPerfTest : public testing::Test {
public:
- PictureLayerTilingPerfTest() : num_runs_(0) {
- tile_manager_ = make_scoped_ptr(new FakeTileManager(&tile_manager_client_));
- picture_layer_tiling_client_ =
- make_scoped_ptr(new FakePictureLayerTilingClient(tile_manager_.get()));
- }
+ PictureLayerTilingPerfTest() : num_runs_(0) {}
virtual void SetUp() OVERRIDE {
- picture_layer_tiling_client_->SetTileSize(gfx::Size(256, 256));
+ picture_layer_tiling_client_.SetTileSize(gfx::Size(256, 256));
picture_layer_tiling_ = PictureLayerTiling::Create(
- 1, gfx::Size(256 * 50, 256 * 50), picture_layer_tiling_client_.get());
- picture_layer_tiling_->CreateTilesForTesting(PENDING_TREE);
+ 1, gfx::Size(256 * 50, 256 * 50), &picture_layer_tiling_client_);
+ picture_layer_tiling_->CreateAllTilesForTesting();
}
virtual void TearDown() OVERRIDE {
@@ -76,7 +70,7 @@
gfx::Size layer_bounds(50 * 256, 50 * 256);
do {
picture_layer_tiling_->UpdateTilePriorities(
- PENDING_TREE,
+ ACTIVE_TREE,
layer_bounds,
gfx::Rect(layer_bounds),
gfx::Rect(layer_bounds),
@@ -110,7 +104,7 @@
const int maxOffsetCount = 1000;
do {
picture_layer_tiling_->UpdateTilePriorities(
- PENDING_TREE,
+ ACTIVE_TREE,
viewport_size,
viewport_rect,
gfx::Rect(layer_bounds),
@@ -140,9 +134,7 @@
}
private:
- FakeTileManagerClient tile_manager_client_;
- scoped_ptr<FakeTileManager> tile_manager_;
- scoped_ptr<FakePictureLayerTilingClient> picture_layer_tiling_client_;
+ FakePictureLayerTilingClient picture_layer_tiling_client_;
scoped_ptr<PictureLayerTiling> picture_layer_tiling_;
base::TimeTicks start_time_;
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index 654b180..5ad2650 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -212,12 +212,6 @@
return *tiling_iter_;
}
-TilePriority PictureLayerTilingSet::CoverageIterator::priority() {
- if (!tiling_iter_)
- return TilePriority();
- return tiling_iter_.priority();
-}
-
PictureLayerTiling* PictureLayerTilingSet::CoverageIterator::CurrentTiling() {
if (current_tiling_ < 0)
return NULL;
diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h
index 29a3c58..29e6bf4 100644
--- a/cc/resources/picture_layer_tiling_set.h
+++ b/cc/resources/picture_layer_tiling_set.h
@@ -95,8 +95,6 @@
Tile* operator->() const;
Tile* operator*() const;
- TilePriority priority();
-
CoverageIterator& operator++();
operator bool() const;
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 0ab1c66..96129c6 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -12,7 +12,6 @@
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
-#include "cc/test/fake_tile_manager.h"
#include "cc/test/fake_tile_manager_client.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/size_conversions.h"
@@ -21,9 +20,7 @@
namespace {
TEST(PictureLayerTilingSetTest, NoResources) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
gfx::Size layer_bounds(1000, 800);
PictureLayerTilingSet set(&client, layer_bounds);
client.SetTileSize(gfx::Size(256, 256));
@@ -71,10 +68,7 @@
scoped_ptr<ResourceProvider> resource_provider =
ResourceProvider::Create(output_surface.get(), NULL, 0, false, 1);
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client, resource_provider.get());
-
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client(resource_provider.get());
client.SetTileSize(gfx::Size(256, 256));
gfx::Size layer_bounds(1000, 800);
PictureLayerTilingSet set(&client, layer_bounds);
@@ -156,24 +150,10 @@
: tile_size_(gfx::Size(10, 10)),
source_bounds_(gfx::Size(30, 20)),
target_bounds_(gfx::Size(30, 30)) {
- output_surface_ = FakeOutputSurface::Create3d();
- CHECK(output_surface_->BindToClient(&output_surface_client_));
- resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
- tile_manager_ = make_scoped_ptr(
- new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
- source_client_ =
- make_scoped_ptr(new FakePictureLayerTilingClient(tile_manager_.get()));
- target_client_ =
- make_scoped_ptr(new FakePictureLayerTilingClient(tile_manager_.get()));
-
- source_client_->SetTileSize(tile_size_);
- target_client_->SetTileSize(tile_size_);
-
- source_.reset(
- new PictureLayerTilingSet(source_client_.get(), source_bounds_));
- target_.reset(
- new PictureLayerTilingSet(target_client_.get(), target_bounds_));
+ source_client_.SetTileSize(tile_size_);
+ target_client_.SetTileSize(tile_size_);
+ source_.reset(new PictureLayerTilingSet(&source_client_, source_bounds_));
+ target_.reset(new PictureLayerTilingSet(&target_client_, target_bounds_));
}
// Sync from source to target.
@@ -181,9 +161,9 @@
const Region& invalidation,
float minimum_scale) {
for (size_t i = 0; i < source_->num_tilings(); ++i)
- source_->tiling_at(i)->CreateTilesForTesting(ACTIVE_TREE);
+ source_->tiling_at(i)->CreateAllTilesForTesting();
for (size_t i = 0; i < target_->num_tilings(); ++i)
- target_->tiling_at(i)->CreateTilesForTesting(PENDING_TREE);
+ target_->tiling_at(i)->CreateAllTilesForTesting();
target_->SyncTilings(
*source_.get(), new_bounds, invalidation, minimum_scale);
@@ -215,8 +195,8 @@
target_tiling->contents_scale());
}
- EXPECT_EQ(source_->client(), source_client_.get());
- EXPECT_EQ(target_->client(), target_client_.get());
+ EXPECT_EQ(source_->client(), &source_client_);
+ EXPECT_EQ(target_->client(), &target_client_);
ValidateTargetTilingSet();
}
@@ -232,7 +212,7 @@
}
for (size_t i = 0; i < target_->num_tilings(); ++i)
- ValidateTiling(target_->tiling_at(i), target_client_->pile());
+ ValidateTiling(target_->tiling_at(i), target_client_.pile());
}
void ValidateTiling(const PictureLayerTiling* tiling,
@@ -242,7 +222,7 @@
else if (!tiling->live_tiles_rect().IsEmpty())
EXPECT_TRUE(tiling->ContentRect().Contains(tiling->live_tiles_rect()));
- std::vector<Tile*> tiles = tiling->TilesForTesting(PENDING_TREE);
+ std::vector<Tile*> tiles = tiling->AllTilesForTesting();
for (size_t i = 0; i < tiles.size(); ++i) {
const Tile* tile = tiles[i];
ASSERT_TRUE(!!tile);
@@ -259,19 +239,13 @@
}
}
- scoped_ptr<FakeOutputSurface> output_surface_;
- FakeOutputSurfaceClient output_surface_client_;
-
gfx::Size tile_size_;
- scoped_ptr<ResourceProvider> resource_provider_;
- scoped_ptr<FakeTileManager> tile_manager_;
- FakeTileManagerClient tile_manager_client_;
- scoped_ptr<FakePictureLayerTilingClient> source_client_;
+ FakePictureLayerTilingClient source_client_;
gfx::Size source_bounds_;
scoped_ptr<PictureLayerTilingSet> source_;
- scoped_ptr<FakePictureLayerTilingClient> target_client_;
+ FakePictureLayerTilingClient target_client_;
gfx::Size target_bounds_;
scoped_ptr<PictureLayerTilingSet> target_;
};
@@ -374,7 +348,7 @@
TEST_F(PictureLayerTilingSetSyncTest, Invalidation) {
source_->AddTiling(2.f);
target_->AddTiling(2.f);
- target_->tiling_at(0)->CreateTilesForTesting(PENDING_TREE);
+ target_->tiling_at(0)->CreateAllTilesForTesting();
Region layer_invalidation;
layer_invalidation.Union(gfx::Rect(0, 0, 1, 1));
@@ -418,7 +392,7 @@
target_->tiling_at(0)->AllTilesForTesting();
EXPECT_GT(original_tiles.size(), 0u);
gfx::Size new_tile_size(100, 100);
- target_client_->SetTileSize(new_tile_size);
+ target_client_.SetTileSize(new_tile_size);
EXPECT_NE(target_->tiling_at(0)->tile_size().ToString(),
new_tile_size.ToString());
diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc
index 530ccc8..6adc611 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -5,13 +5,10 @@
#include "cc/resources/picture_layer_tiling.h"
#include <limits>
-#include <set>
#include "cc/base/math_util.h"
#include "cc/resources/picture_layer_tiling_set.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
-#include "cc/test/fake_tile_manager.h"
-#include "cc/test/fake_tile_manager_client.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/size_conversions.h"
@@ -19,12 +16,6 @@
namespace cc {
namespace {
-const int kTileBundleWidth = 2;
-const int kTileBundleHeight = 2;
-std::pair<int, int> ComputeTileBundleIndex(int i, int j) {
- return std::make_pair(i / kTileBundleWidth, j / kTileBundleHeight);
-}
-
static gfx::Rect ViewportInLayerSpace(
const gfx::Transform& transform,
gfx::Size device_viewport) {
@@ -43,7 +34,6 @@
public:
using PictureLayerTiling::SetLiveTilesRect;
using PictureLayerTiling::TileAt;
- using PictureLayerTiling::TileBundleAt;
static scoped_ptr<TestablePictureLayerTiling> Create(
float contents_scale,
@@ -55,9 +45,6 @@
client));
}
- TilingData tiling_data() const { return tiling_data_; }
- TilingData bundle_tiling_data() const { return bundle_tiling_data_; }
-
protected:
TestablePictureLayerTiling(float contents_scale,
gfx::Size layer_bounds,
@@ -67,9 +54,7 @@
class PictureLayerTilingIteratorTest : public testing::Test {
public:
- PictureLayerTilingIteratorTest()
- : tile_manager_(&tile_manager_client_), client_(&tile_manager_) {}
-
+ PictureLayerTilingIteratorTest() {}
virtual ~PictureLayerTilingIteratorTest() {}
void Initialize(gfx::Size tile_size,
@@ -82,7 +67,6 @@
}
void SetLiveRectAndVerifyTiles(gfx::Rect live_tiles_rect) {
- tiling_->SetTreeForTesting(ACTIVE_TREE);
tiling_->SetLiveTilesRect(live_tiles_rect);
std::vector<Tile*> tiles = tiling_->AllTilesForTesting();
@@ -169,8 +153,6 @@
}
protected:
- FakeTileManagerClient tile_manager_client_;
- FakeTileManager tile_manager_;
FakePictureLayerTilingClient client_;
scoped_ptr<TestablePictureLayerTiling> tiling_;
@@ -279,107 +261,6 @@
VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, 100, 2000, 100));
}
-TEST(PictureLayerTilingTest, BundleAtContainsTileAt) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
-
- gfx::Size current_layer_bounds(400, 400);
- client.SetTileSize(gfx::Size(100, 100));
- scoped_ptr<TestablePictureLayerTiling> tiling =
- TestablePictureLayerTiling::Create(1.0f, current_layer_bounds, &client);
-
- tiling->CreateTilesForTesting(ACTIVE_TREE);
- for (int bundle_y = 0;
- bundle_y < (current_layer_bounds.height() / (kTileBundleHeight * 100));
- ++bundle_y) {
- for (int bundle_x = 0;
- bundle_x < (current_layer_bounds.width() / (kTileBundleWidth * 100));
- ++bundle_x) {
- EXPECT_TRUE(tiling->TileBundleAt(bundle_x, bundle_y))
- << "bundle_x " << bundle_x << " bundle_y " << bundle_y;
-
- TileBundle* bundle = tiling->TileBundleAt(bundle_x, bundle_y);
- for (int tile_y = 0; tile_y < kTileBundleWidth; ++tile_y) {
- for (int tile_x = 0; tile_x < kTileBundleHeight; ++tile_x) {
- int global_tile_x = bundle_x * kTileBundleWidth + tile_x;
- int global_tile_y = bundle_y * kTileBundleHeight + tile_y;
-
- EXPECT_TRUE(tiling->TileAt(ACTIVE_TREE, global_tile_x, global_tile_y))
- << "x " << global_tile_x << " y " << global_tile_y;
- EXPECT_EQ(tiling->TileAt(ACTIVE_TREE, global_tile_x, global_tile_y),
- bundle->TileAt(ACTIVE_TREE, global_tile_x, global_tile_y))
- << "x " << global_tile_x << " y " << global_tile_y;
- }
- }
- }
- }
-}
-
-TEST(PictureLayerTilingTest, TilesCleanedUp) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
- FakePictureLayerTilingClient twin_client(&tile_manager);
-
- gfx::Size current_layer_bounds(400, 400);
- client.SetTileSize(gfx::Size(100, 100));
- twin_client.SetTileSize(gfx::Size(100, 100));
- scoped_ptr<TestablePictureLayerTiling> tiling =
- TestablePictureLayerTiling::Create(1.0f, current_layer_bounds, &client);
- scoped_ptr<TestablePictureLayerTiling> twin_tiling =
- TestablePictureLayerTiling::Create(
- 1.0f, current_layer_bounds, &twin_client);
-
- client.set_twin_tiling(twin_tiling.get());
- twin_client.set_twin_tiling(tiling.get());
-
- tiling->CreateTilesForTesting(ACTIVE_TREE);
- twin_tiling->CreateTilesForTesting(PENDING_TREE);
- for (int tile_y = 0; tile_y < 4; ++tile_y) {
- for (int tile_x = 0; tile_x < 4; ++tile_x) {
- EXPECT_TRUE(tiling->TileAt(ACTIVE_TREE, tile_x, tile_y) ==
- twin_tiling->TileAt(ACTIVE_TREE, tile_x, tile_y));
- EXPECT_TRUE(tiling->TileAt(PENDING_TREE, tile_x, tile_y) ==
- twin_tiling->TileAt(PENDING_TREE, tile_x, tile_y));
- }
- }
-
- client.set_twin_tiling(NULL);
- twin_tiling.reset();
-
- for (int tile_y = 0; tile_y < 4; ++tile_y) {
- for (int tile_x = 0; tile_x < 4; ++tile_x) {
- EXPECT_TRUE(tiling->TileAt(ACTIVE_TREE, tile_x, tile_y) != NULL);
- EXPECT_TRUE(tiling->TileAt(PENDING_TREE, tile_x, tile_y) == NULL);
- }
- }
-}
-
-TEST(PictureLayerTilingTest, DidBecomeActiveSwapsTiles) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
-
- gfx::Size current_layer_bounds(400, 400);
- client.SetTileSize(gfx::Size(100, 100));
- scoped_ptr<TestablePictureLayerTiling> tiling =
- TestablePictureLayerTiling::Create(1.0f, current_layer_bounds, &client);
-
- tiling->CreateTilesForTesting(ACTIVE_TREE);
- std::vector<Tile*> old_active_tiles = tiling->TilesForTesting(ACTIVE_TREE);
- tiling->DidBecomeActive();
- std::vector<Tile*> pending_tiles = tiling->TilesForTesting(PENDING_TREE);
- EXPECT_EQ(old_active_tiles.size(), pending_tiles.size());
- std::vector<Tile*>::const_iterator old_it = old_active_tiles.begin();
- for (std::vector<Tile*>::const_iterator it = pending_tiles.begin();
- it != pending_tiles.end();
- ++it) {
- EXPECT_EQ(*it, *old_it);
- ++old_it;
- }
-}
-
TEST(PictureLayerTilingTest, ExpandRectEqual) {
gfx::Rect in(40, 50, 100, 200);
gfx::Rect bounds(-1000, -1000, 10000, 10000);
@@ -851,64 +732,11 @@
base::Bind(&TileExists, true));
}
-TEST_F(PictureLayerTilingIteratorTest, BundlesAndTilesAlign) {
- Initialize(gfx::Size(100, 100), 1, gfx::Size(850, 850));
- for (int y = -20; y <= 102; ++y) {
- for (int x = 0; x <= 103; ++x) {
- for (int size = 1; size <= 201; size += 50) {
- gfx::Rect rect(x, y, size, size);
-
- TilingData tiling_data = tiling_->tiling_data();
-
- std::set<std::pair<int, int> > tile_positions;
- std::set<std::pair<int, int> > predicted_bundle_positions;
- size_t iteration_count = 0;
- for (TilingData::Iterator iter(&tiling_data, rect); iter; ++iter) {
- ++iteration_count;
- tile_positions.insert(std::make_pair(iter.index_x(), iter.index_y()));
- predicted_bundle_positions.insert(
- ComputeTileBundleIndex(iter.index_x(), iter.index_y()));
- }
-
- ASSERT_EQ(tile_positions.size(), iteration_count) << rect.ToString();
-
- TilingData bundle_tiling_data = tiling_->bundle_tiling_data();
- std::set<std::pair<int, int> > bundle_positions;
- iteration_count = 0;
- for (TilingData::Iterator iter(&bundle_tiling_data, rect);
- iter;
- ++iter) {
- ++iteration_count;
- bundle_positions.insert(
- std::make_pair(iter.index_x(), iter.index_y()));
- }
-
- ASSERT_EQ(bundle_positions.size(), iteration_count) << rect.ToString();
- ASSERT_EQ(predicted_bundle_positions.size(), iteration_count)
- << rect.ToString();
-
- std::set<std::pair<int, int> >::const_iterator predicted_iterator =
- predicted_bundle_positions.begin();
- for (std::set<std::pair<int, int> >::const_iterator actual_iterator =
- bundle_positions.begin();
- actual_iterator != bundle_positions.end();
- ++actual_iterator) {
- ASSERT_EQ(*actual_iterator, *predicted_iterator) << rect.ToString();
- ++predicted_iterator;
- }
- }
- }
- }
-}
-
-
TEST(UpdateTilePrioritiesTest, VisibleTiles) {
// The TilePriority of visible tiles should have zero distance_to_visible
// and time_to_visible.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
@@ -944,13 +772,24 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 0, 0));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 0, 1));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 1, 0));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 1, 1));
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
+ EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
+
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
+ EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
+
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
+ EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
+
+ priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
}
@@ -959,15 +798,13 @@
// The TilePriority of offscreen tiles (without movement) should have nonzero
// distance_to_visible and infinite time_to_visible.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen; nothing is visible.
- gfx::Size last_layer_bounds(400, 400);
- gfx::Size current_layer_bounds(400, 400);
+ gfx::Size last_layer_bounds(200, 200);
+ gfx::Size current_layer_bounds(200, 200);
float last_layer_contents_scale = 1.f;
float current_layer_contents_scale = 1.f;
gfx::Transform last_screen_transform;
@@ -1000,34 +837,40 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 0, 0));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 0, 1));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 1, 0));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 1, 1));
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 2, 2));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 2, 3));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 3, 2));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 3, 3));
- ASSERT_TRUE(tiling->TileBundleAt(0, 1));
- ASSERT_TRUE(tiling->TileBundleAt(1, 0));
- ASSERT_TRUE(tiling->TileBundleAt(1, 1));
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
+ EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
+ EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
+ priority.time_to_visible_in_seconds);
- // Furthermore, in this scenario bundles on the right hand side should have a
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
+ EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
+ EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
+ priority.time_to_visible_in_seconds);
+
+ priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
+ EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
+ EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
+ priority.time_to_visible_in_seconds);
+
+ // Furthermore, in this scenario tiles on the right hand side should have a
// larger distance to visible.
- TilePriority left = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
- TilePriority right = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
+ TilePriority right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
EXPECT_GT(right.distance_to_visible_in_pixels,
left.distance_to_visible_in_pixels);
- left = tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
- right = tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
+ right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(right.distance_to_visible_in_pixels,
left.distance_to_visible_in_pixels);
}
@@ -1036,15 +879,13 @@
// Sanity check that a layer with some tiles visible and others offscreen has
// correct TilePriorities for each tile.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
gfx::Rect visible_layer_rect(0, 0, 100, 100); // only top quarter.
- gfx::Size last_layer_bounds(400, 400);
- gfx::Size current_layer_bounds(400, 400);
+ gfx::Size last_layer_bounds(200, 200);
+ gfx::Size current_layer_bounds(200, 200);
float last_layer_contents_scale = 1.f;
float current_layer_contents_scale = 1.f;
gfx::Transform last_screen_transform;
@@ -1077,30 +918,26 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 0, 0));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 0, 1));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 1, 0));
- ASSERT_TRUE(tiling->TileAt(ACTIVE_TREE, 1, 1));
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
- ASSERT_TRUE(tiling->TileBundleAt(0, 1));
- ASSERT_TRUE(tiling->TileBundleAt(1, 0));
- ASSERT_TRUE(tiling->TileBundleAt(1, 1));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
@@ -1111,15 +948,13 @@
// that UpdateTilePriorities correctly accounts for the transform between
// layer space and screen space.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
gfx::Rect visible_layer_rect(0, 0, 100, 100); // only top-left quarter.
- gfx::Size last_layer_bounds(400, 400);
- gfx::Size current_layer_bounds(400, 400);
+ gfx::Size last_layer_bounds(200, 200);
+ gfx::Size current_layer_bounds(200, 200);
float last_layer_contents_scale = 1.f;
float current_layer_contents_scale = 1.f;
gfx::Transform last_screen_transform;
@@ -1155,38 +990,36 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
- ASSERT_TRUE(tiling->TileBundleAt(0, 1));
- ASSERT_TRUE(tiling->TileBundleAt(1, 0));
- ASSERT_TRUE(tiling->TileBundleAt(1, 1));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
// Furthermore, in this scenario the bottom-right tile should have the larger
// distance to visible.
- TilePriority top_left = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
- TilePriority top_right = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
- TilePriority bottom_left =
- tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
- TilePriority bottom_right =
- tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
+ TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
+ TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
+ TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(top_right.distance_to_visible_in_pixels,
top_left.distance_to_visible_in_pixels);
EXPECT_GT(bottom_left.distance_to_visible_in_pixels,
@@ -1202,15 +1035,13 @@
// Perspective transforms need to take a different code path.
// This test checks tile priorities of a perspective layer.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen.
- gfx::Size last_layer_bounds(400, 400);
- gfx::Size current_layer_bounds(400, 400);
+ gfx::Size last_layer_bounds(200, 200);
+ gfx::Size current_layer_bounds(200, 200);
float last_layer_contents_scale = 1.f;
float current_layer_contents_scale = 1.f;
gfx::Transform last_screen_transform;
@@ -1261,29 +1092,29 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
- ASSERT_TRUE(tiling->TileBundleAt(0, 1));
- ASSERT_TRUE(tiling->TileBundleAt(1, 0));
- ASSERT_TRUE(tiling->TileBundleAt(1, 1));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
// All tiles will have a positive distance_to_visible
// and an infinite time_to_visible.
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
@@ -1291,12 +1122,10 @@
// Furthermore, in this scenario the top-left distance_to_visible
// will be smallest, followed by top-right. The bottom layers
// will of course be further than the top layers.
- TilePriority top_left = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
- TilePriority top_right = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
- TilePriority bottom_left =
- tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
- TilePriority bottom_right =
- tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
+ TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
+ TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
+ TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(top_right.distance_to_visible_in_pixels,
top_left.distance_to_visible_in_pixels);
@@ -1311,15 +1140,13 @@
// Perspective transforms need to take a different code path.
// This test checks tile priorities of a perspective layer.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen.
- gfx::Size last_layer_bounds(400, 400);
- gfx::Size current_layer_bounds(400, 400);
+ gfx::Size last_layer_bounds(200, 200);
+ gfx::Size current_layer_bounds(200, 200);
float last_layer_contents_scale = 1.f;
float current_layer_contents_scale = 1.f;
gfx::Transform last_screen_transform;
@@ -1335,22 +1162,22 @@
// Translate layer to offscreen
current_screen_transform.Translate(400.0, 970.0);
// Apply perspective and rotation about the center of the layer
- current_screen_transform.Translate(200.0, 200.0);
+ current_screen_transform.Translate(100.0, 100.0);
current_screen_transform.ApplyPerspectiveDepth(10.0);
current_screen_transform.RotateAboutYAxis(10.0);
- current_screen_transform.Translate(-200.0, -200.0);
+ current_screen_transform.Translate(-100.0, -100.0);
last_screen_transform = current_screen_transform;
// Sanity check that this transform does cause w<0 clipping for the left side
// of the layer, but not the right side.
bool clipped;
MathUtil::MapQuad(current_screen_transform,
- gfx::QuadF(gfx::RectF(0, 0, 200, 400)),
+ gfx::QuadF(gfx::RectF(0, 0, 100, 200)),
&clipped);
ASSERT_TRUE(clipped);
MathUtil::MapQuad(current_screen_transform,
- gfx::QuadF(gfx::RectF(200, 0, 200, 400)),
+ gfx::QuadF(gfx::RectF(100, 0, 100, 200)),
&clipped);
ASSERT_FALSE(clipped);
@@ -1376,29 +1203,29 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
- ASSERT_TRUE(tiling->TileBundleAt(0, 1));
- ASSERT_TRUE(tiling->TileBundleAt(1, 0));
- ASSERT_TRUE(tiling->TileBundleAt(1, 1));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
// Left-side tiles will be clipped by the transform, so we have to assume
// they are visible just in case.
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
// Right-side tiles will have a positive distance_to_visible
// and an infinite time_to_visible.
- priority = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
@@ -1408,9 +1235,7 @@
// Test that time_to_visible is computed correctly when
// there is some motion.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
@@ -1432,7 +1257,7 @@
gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
current_screen_transform, device_viewport);
- client.SetTileSize(gfx::Size(50, 50));
+ client.SetTileSize(gfx::Size(100, 100));
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
@@ -1467,32 +1292,31 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
- ASSERT_TRUE(tiling->TileBundleAt(0, 1));
- ASSERT_TRUE(tiling->TileBundleAt(1, 0));
- ASSERT_TRUE(tiling->TileBundleAt(1, 1));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(1.f,
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(1.f,
priority.time_to_visible_in_seconds);
- // time_to_visible for the right hand side layers needs an extra 0.097
- // seconds because this bundle is
- // |(50 - 2 * border_texels) * 2 + border_texels| = 97 pixels further away.
- priority = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
+ // time_to_visible for the right hand side layers needs an extra 0.099
+ // seconds because this tile is 99 pixels further away.
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
- EXPECT_FLOAT_EQ(1.097f,
+ EXPECT_FLOAT_EQ(1.099f,
priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(1, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
- EXPECT_FLOAT_EQ(1.097f,
+ EXPECT_FLOAT_EQ(1.099f,
priority.time_to_visible_in_seconds);
}
@@ -1501,9 +1325,7 @@
// that UpdateTilePriorities correctly accounts for the transform between
// layer space and screen space.
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- FakePictureLayerTilingClient client(&tile_manager);
+ FakePictureLayerTilingClient client;
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Size device_viewport(800, 600);
@@ -1533,7 +1355,7 @@
gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
current_screen_transform, device_viewport);
- client.SetTileSize(gfx::Size(50, 50));
+ client.SetTileSize(gfx::Size(100, 100));
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
@@ -1568,20 +1390,20 @@
current_frame_time_in_seconds,
max_tiles_for_interest_area);
- ASSERT_TRUE(tiling->TileBundleAt(0, 0));
- ASSERT_TRUE(tiling->TileBundleAt(0, 1));
- ASSERT_TRUE(tiling->TileBundleAt(1, 0));
- ASSERT_TRUE(tiling->TileBundleAt(1, 1));
+ ASSERT_TRUE(tiling->TileAt(0, 0));
+ ASSERT_TRUE(tiling->TileAt(0, 1));
+ ASSERT_TRUE(tiling->TileAt(1, 0));
+ ASSERT_TRUE(tiling->TileAt(1, 1));
- TilePriority priority = tiling->TileBundleAt(0, 0)->GetPriority(ACTIVE_TREE);
+ TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible_in_pixels);
EXPECT_FLOAT_EQ(0.f, priority.time_to_visible_in_seconds);
- priority = tiling->TileBundleAt(0, 1)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_GT(priority.time_to_visible_in_seconds, 0.f);
- priority = tiling->TileBundleAt(1, 0)->GetPriority(ACTIVE_TREE);
+ priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
EXPECT_GT(priority.distance_to_visible_in_pixels, 0.f);
EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
priority.time_to_visible_in_seconds);
diff --git a/cc/resources/prioritized_resource_manager.cc b/cc/resources/prioritized_resource_manager.cc
index 43d4f52..da8f055 100644
--- a/cc/resources/prioritized_resource_manager.cc
+++ b/cc/resources/prioritized_resource_manager.cc
@@ -326,10 +326,14 @@
continue;
wasted_memory += (*it)->bytes();
}
- size_t ten_percent_of_memory = memory_available_bytes_ / 10;
- if (wasted_memory > ten_percent_of_memory)
+ size_t wasted_memory_to_allow = memory_available_bytes_ / 10;
+ // If the external priority cutoff indicates that unused memory should be
+ // freed, then do not allow any memory for texture recycling.
+ if (external_priority_cutoff_ != PriorityCalculator::AllowEverythingCutoff())
+ wasted_memory_to_allow = 0;
+ if (wasted_memory > wasted_memory_to_allow)
EvictBackingsToReduceMemory(MemoryUseBytes() -
- (wasted_memory - ten_percent_of_memory),
+ (wasted_memory - wasted_memory_to_allow),
PriorityCalculator::AllowEverythingCutoff(),
EVICT_ONLY_RECYCLABLE,
DO_NOT_UNLINK_BACKINGS,
diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc
index 4526341..b51eb00 100644
--- a/cc/resources/prioritized_tile_set_unittest.cc
+++ b/cc/resources/prioritized_tile_set_unittest.cc
@@ -8,7 +8,6 @@
#include "cc/resources/managed_tile_state.h"
#include "cc/resources/prioritized_tile_set.h"
#include "cc/resources/tile.h"
-#include "cc/resources/tile_bundle.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_pile_impl.h"
@@ -79,18 +78,6 @@
Tile::USE_LCD_TEXT);
}
- scoped_refptr<Tile> CreateTileWithPriority(
- const TilePriority& priority) {
- scoped_refptr<TileBundle> bundle =
- tile_manager_->CreateTileBundle(0, 0, 1, 1);
- scoped_refptr<Tile> tile = CreateTile();
- bundle->AddTileAt(ACTIVE_TREE, 0, 0, tile);
- bundle->AddTileAt(PENDING_TREE, 0, 0, tile);
- bundle->SetPriority(ACTIVE_TREE, priority);
- bundle->SetPriority(PENDING_TREE, priority);
- return tile;
- }
-
private:
LayerTreeSettings settings_;
FakeOutputSurfaceClient output_surface_client_;
@@ -136,7 +123,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
tiles.push_back(tile);
set.InsertTile(tile, NOW_AND_READY_TO_DRAW_BIN);
}
@@ -166,7 +155,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
tiles.push_back(tile);
set.InsertTile(tile, NOW_BIN);
}
@@ -198,7 +189,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ 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);
}
@@ -231,7 +224,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ 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);
}
@@ -260,7 +255,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
tiles.push_back(tile);
set.InsertTile(tile, EVENTUALLY_AND_ACTIVE_BIN);
}
@@ -292,7 +289,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
tiles.push_back(tile);
set.InsertTile(tile, EVENTUALLY_BIN);
}
@@ -324,7 +323,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
tiles.push_back(tile);
set.InsertTile(tile, AT_LAST_AND_ACTIVE_BIN);
}
@@ -356,7 +357,9 @@
std::vector<scoped_refptr<Tile> > tiles;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
tiles.push_back(tile);
set.InsertTile(tile, AT_LAST_BIN);
}
@@ -436,7 +439,9 @@
PrioritizedTileSet set;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ 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);
@@ -545,7 +550,9 @@
PrioritizedTileSet set;
for (int priority = 0; priority < 4; ++priority) {
for (int i = 0; i < 5; ++i) {
- scoped_refptr<Tile> tile = CreateTileWithPriority(priorities[priority]);
+ 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);
diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc
index c9ec154..2097806 100644
--- a/cc/resources/tile.cc
+++ b/cc/resources/tile.cc
@@ -31,8 +31,6 @@
layer_id_(layer_id),
source_frame_number_(source_frame_number),
flags_(flags),
- required_for_activation_(false),
- is_visible_(false),
id_(s_next_id_++) {
set_picture_pile(picture_pile);
}
@@ -43,11 +41,19 @@
"cc::Tile", this);
}
-void Tile::MarkRequiredForActivation() {
- if (required_for_activation_)
+void Tile::SetPriority(WhichTree tree, const TilePriority& priority) {
+ if (priority == priority_[tree])
return;
- required_for_activation_ = true;
+ priority_[tree] = priority;
+ tile_manager_->DidChangeTilePriority(this);
+}
+
+void Tile::MarkRequiredForActivation() {
+ if (priority_[PENDING_TREE].required_for_activation)
+ return;
+
+ priority_[PENDING_TREE].required_for_activation = true;
tile_manager_->DidChangeTilePriority(this);
}
@@ -60,10 +66,11 @@
res->SetDouble("contents_scale", contents_scale_);
res->Set("content_rect", MathUtil::AsValue(content_rect_).release());
res->SetInteger("layer_id", layer_id_);
+ res->Set("active_priority", priority_[ACTIVE_TREE].AsValue().release());
+ res->Set("pending_priority", priority_[PENDING_TREE].AsValue().release());
res->Set("managed_state", managed_state_.AsValue().release());
res->SetBoolean("can_use_lcd_text", can_use_lcd_text());
res->SetBoolean("use_gpu_rasterization", use_gpu_rasterization());
- res->SetBoolean("required_for_activation", required_for_activation_);
return res.PassAs<base::Value>();
}
diff --git a/cc/resources/tile.h b/cc/resources/tile.h
index 548d9c9..e7c9636 100644
--- a/cc/resources/tile.h
+++ b/cc/resources/tile.h
@@ -11,7 +11,7 @@
#include "cc/base/ref_counted_managed.h"
#include "cc/resources/managed_tile_state.h"
#include "cc/resources/raster_mode.h"
-#include "cc/resources/tile_bundle.h"
+#include "cc/resources/tile_priority.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
@@ -40,10 +40,21 @@
return picture_pile_.get();
}
+ const TilePriority& priority(WhichTree tree) const {
+ return priority_[tree];
+ }
+
+ TilePriority combined_priority() const {
+ return TilePriority(priority_[ACTIVE_TREE],
+ priority_[PENDING_TREE]);
+ }
+
+ void SetPriority(WhichTree tree, const TilePriority& priority);
+
void MarkRequiredForActivation();
bool required_for_activation() const {
- return required_for_activation_;
+ return priority_[PENDING_TREE].required_for_activation;
}
void set_can_use_lcd_text(bool can_use_lcd_text) {
@@ -68,14 +79,6 @@
return !!(flags_ & USE_GPU_RASTERIZATION);
}
- bool is_visible() const {
- return is_visible_;
- }
-
- void set_is_visible(bool is_visible) {
- is_visible_ = is_visible;
- }
-
scoped_ptr<base::Value> AsValue() const;
inline bool IsReadyToDraw() const {
@@ -151,12 +154,11 @@
float contents_scale_;
gfx::Rect opaque_rect_;
+ TilePriority priority_[NUM_TREES];
ManagedTileState managed_state_;
int layer_id_;
int source_frame_number_;
int flags_;
- bool required_for_activation_;
- bool is_visible_;
Id id_;
static Id s_next_id_;
diff --git a/cc/resources/tile_bundle.cc b/cc/resources/tile_bundle.cc
deleted file mode 100644
index e99b9f2..0000000
--- a/cc/resources/tile_bundle.cc
+++ /dev/null
@@ -1,181 +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/resources/tile_bundle.h"
-
-#include <algorithm>
-
-#include "cc/resources/picture_layer_tiling.h"
-#include "cc/resources/tile.h"
-#include "cc/resources/tile_manager.h"
-
-namespace cc {
-
-TileBundle::Id TileBundle::s_next_id_ = 0;
-
-TileBundle::TileBundle(TileManager* tile_manager,
- int offset_x,
- int offset_y,
- int width,
- int height)
- : RefCountedManaged<TileBundle>(tile_manager),
- tile_manager_(tile_manager),
- index_offset_x_(offset_x),
- index_offset_y_(offset_y),
- index_count_x_(width),
- index_count_y_(height),
- conservative_tile_count_(0),
- needs_tile_swap_(false),
- id_(s_next_id_++) {
- tiles_[ACTIVE_TREE].resize(index_count_y_);
- for (int i = 0; i < index_count_y_; ++i)
- tiles_[ACTIVE_TREE][i].resize(index_count_x_);
-
- tiles_[PENDING_TREE].resize(index_count_y_);
- for (int i = 0; i < index_count_y_; ++i)
- tiles_[PENDING_TREE][i].resize(index_count_x_);
-}
-
-TileBundle::~TileBundle() {}
-
-Tile* TileBundle::TileAt(WhichTree tree, int index_x, int index_y) {
- DCHECK(!needs_tile_swap_);
-
- UpdateToLocalIndex(&index_x, &index_y);
- return TileAtLocalIndex(tree, index_x, index_y);
-}
-
-Tile* TileBundle::TileAtLocalIndex(WhichTree tree, int index_x, int index_y) {
- return tiles_[tree][index_y][index_x].get();
-}
-
-void TileBundle::SetPriority(WhichTree tree, const TilePriority& priority) {
- DCHECK(!needs_tile_swap_);
-
- if (priority_[tree] == priority)
- return;
-
- priority_[tree] = priority;
- tile_manager_->DidChangeTileBundlePriority(this);
-}
-
-TilePriority TileBundle::GetPriority(WhichTree tree) const {
- return priority_[tree];
-}
-
-bool TileBundle::RemoveTileAt(WhichTree tree, int index_x, int index_y) {
- DCHECK(!needs_tile_swap_);
-
- UpdateToLocalIndex(&index_x, &index_y);
- bool removed = !!tiles_[tree][index_y][index_x];
- tiles_[tree][index_y][index_x] = NULL;
- if (removed)
- --conservative_tile_count_;
- return removed;
-}
-
-void TileBundle::AddTileAt(WhichTree tree,
- int index_x,
- int index_y,
- scoped_refptr<Tile> tile) {
- DCHECK(!needs_tile_swap_);
-
- UpdateToLocalIndex(&index_x, &index_y);
- DCHECK(!tiles_[tree][index_y][index_x]);
- tiles_[tree][index_y][index_x] = tile;
- ++conservative_tile_count_;
-}
-
-void TileBundle::DidBecomeRecycled() {
- priority_[ACTIVE_TREE] = TilePriority();
- needs_tile_swap_ = !needs_tile_swap_;
-}
-
-void TileBundle::DidBecomeActive() {
- priority_[ACTIVE_TREE] = priority_[PENDING_TREE];
- priority_[PENDING_TREE] = TilePriority();
- tiles_[ACTIVE_TREE].swap(tiles_[PENDING_TREE]);
- needs_tile_swap_ = false;
-}
-
-void TileBundle::UpdateToLocalIndex(int* index_x, int* index_y) {
- DCHECK(index_x);
- DCHECK(index_y);
-
- *index_x -= index_offset_x_;
- *index_y -= index_offset_y_;
-
- DCHECK_GE(*index_x, 0);
- DCHECK_GE(*index_y, 0);
- DCHECK_LT(*index_x, index_count_x_);
- DCHECK_LT(*index_x, index_count_y_);
-}
-
-void TileBundle::SwapTilesIfRequired() {
- if (!needs_tile_swap_)
- return;
-
- std::swap(priority_[ACTIVE_TREE], priority_[PENDING_TREE]);
- tiles_[ACTIVE_TREE].swap(tiles_[PENDING_TREE]);
- needs_tile_swap_ = false;
-}
-
-TileBundle::Iterator::Iterator(TileBundle* bundle)
- : bundle_(bundle),
- current_tile_(NULL),
- index_x_(0),
- index_y_(0),
- current_tree_(ACTIVE_TREE),
- min_tree_(ACTIVE_TREE),
- max_tree_(PENDING_TREE) {
- if (!InitializeNewTile())
- ++(*this);
-}
-
-TileBundle::Iterator::Iterator(TileBundle* bundle, WhichTree tree)
- : bundle_(bundle),
- current_tile_(NULL),
- index_x_(0),
- index_y_(0),
- current_tree_(tree),
- min_tree_(tree),
- max_tree_(tree) {
- if (!InitializeNewTile())
- ++(*this);
-}
-
-TileBundle::Iterator::~Iterator() {}
-
-TileBundle::Iterator& TileBundle::Iterator::operator++() {
- do {
- current_tree_ = static_cast<WhichTree>(current_tree_ + 1);
- if (current_tree_ > max_tree_) {
- current_tree_ = min_tree_;
- ++index_x_;
- if (index_x_ >= bundle_->index_count_x_) {
- index_x_ = 0;
- ++index_y_;
- if (index_y_ >= bundle_->index_count_y_)
- break;
- }
- }
- } while (!InitializeNewTile());
-
- return *this;
-}
-
-bool TileBundle::Iterator::InitializeNewTile() {
- Tile* tile = bundle_->TileAtLocalIndex(current_tree_, index_x_, index_y_);
-
- // We succeed only if we have a tile and it is different
- // from what we currently have. This is to avoid the iterator
- // returning the same tile twice when it's shared between trees.
- if (!tile || tile == current_tile_)
- return false;
-
- current_tile_ = tile;
- return true;
-}
-
-} // namespace cc
diff --git a/cc/resources/tile_bundle.h b/cc/resources/tile_bundle.h
deleted file mode 100644
index ba113df..0000000
--- a/cc/resources/tile_bundle.h
+++ /dev/null
@@ -1,115 +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_RESOURCES_TILE_BUNDLE_H_
-#define CC_RESOURCES_TILE_BUNDLE_H_
-
-#include <utility>
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "cc/base/ref_counted_managed.h"
-#include "cc/resources/tile_priority.h"
-
-namespace cc {
-
-class TileManager;
-class Tile;
-class PictureLayerTiling;
-
-class CC_EXPORT TileBundle : public RefCountedManaged<TileBundle> {
- public:
- typedef uint64 Id;
- typedef std::vector<scoped_refptr<Tile> > TileVector;
- typedef std::vector<TileVector> TileGrid;
-
- inline Id id() const { return id_; }
-
- Tile* TileAt(WhichTree tree, int index_x, int index_y);
- bool RemoveTileAt(WhichTree tree, int index_x, int index_y);
- void AddTileAt(WhichTree tree,
- int index_x,
- int index_y,
- scoped_refptr<Tile> tile);
- bool IsEmpty() const { return conservative_tile_count_ == 0; }
-
- void DidBecomeRecycled();
- void DidBecomeActive();
-
- void SetPriority(WhichTree tree, const TilePriority& priority);
- TilePriority GetPriority(WhichTree tree) const;
-
- void SwapTilesIfRequired();
-
- class CC_EXPORT Iterator {
- public:
- explicit Iterator(TileBundle* bundle);
- Iterator(TileBundle* bundle, WhichTree tree);
- ~Iterator();
-
- Iterator& operator++();
-
- inline Tile* operator*() { return current_tile_; }
- inline Tile* operator->() { return current_tile_; }
- inline operator bool() const {
- return index_y_ < bundle_->index_count_y_;
- }
-
- inline int index_x() {
- return index_x_ + bundle_->index_offset_x_;
- }
- inline int index_y() {
- return index_y_ + bundle_->index_offset_y_;
- }
-
- TilePriority priority(WhichTree tree) const {
- return bundle_->GetPriority(tree);
- }
-
- private:
- bool InitializeNewTile();
-
- TileBundle* bundle_;
- Tile* current_tile_;
- int index_x_;
- int index_y_;
- WhichTree current_tree_;
-
- WhichTree min_tree_;
- WhichTree max_tree_;
- };
-
- private:
- friend class TileManager;
- friend class Iterator;
-
- TileBundle(TileManager* tile_manager,
- int offset_x,
- int offset_y,
- int width,
- int height);
- ~TileBundle();
-
- void UpdateToLocalIndex(int* index_x, int* index_y);
- Tile* TileAtLocalIndex(WhichTree tree, int x, int y);
-
- TileManager* tile_manager_;
-
- TileGrid tiles_[NUM_TREES];
- int index_offset_x_;
- int index_offset_y_;
- int index_count_x_;
- int index_count_y_;
-
- TilePriority priority_[NUM_TREES];
- int conservative_tile_count_;
- bool needs_tile_swap_;
-
- Id id_;
- static Id s_next_id_;
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_TILE_BUNDLE_H_
diff --git a/cc/resources/tile_bundle_unittest.cc b/cc/resources/tile_bundle_unittest.cc
deleted file mode 100644
index 268bdc4..0000000
--- a/cc/resources/tile_bundle_unittest.cc
+++ /dev/null
@@ -1,257 +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/resources/tile_bundle.h"
-
-#include <set>
-
-#include "cc/test/fake_picture_pile_impl.h"
-#include "cc/test/fake_tile_manager.h"
-#include "cc/test/fake_tile_manager_client.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-TEST(TileBundle, AddRemoveTile) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- scoped_refptr<PicturePileImpl> picture_pile =
- FakePicturePileImpl::CreatePile();
-
- scoped_refptr<Tile> tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
- scoped_refptr<TileBundle> bundle = tile_manager.CreateTileBundle(0, 0, 2, 2);
-
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 1));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 1));
- EXPECT_TRUE(bundle->IsEmpty());
-
- bundle->AddTileAt(ACTIVE_TREE, 0, 1, tile);
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 0));
- EXPECT_TRUE(bundle->TileAt(ACTIVE_TREE, 0, 1));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 1));
- EXPECT_FALSE(bundle->IsEmpty());
-
- bundle->AddTileAt(ACTIVE_TREE, 1, 1, tile);
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 0));
- EXPECT_TRUE(bundle->TileAt(ACTIVE_TREE, 0, 1));
- EXPECT_TRUE(bundle->TileAt(ACTIVE_TREE, 1, 1));
- EXPECT_FALSE(bundle->IsEmpty());
-
- bundle->RemoveTileAt(ACTIVE_TREE, 0, 1);
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 1));
- EXPECT_TRUE(bundle->TileAt(ACTIVE_TREE, 1, 1));
- EXPECT_FALSE(bundle->IsEmpty());
-
- bundle->RemoveTileAt(ACTIVE_TREE, 0, 1);
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 1));
- EXPECT_TRUE(bundle->TileAt(ACTIVE_TREE, 1, 1));
- EXPECT_FALSE(bundle->IsEmpty());
-
- bundle->RemoveTileAt(ACTIVE_TREE, 1, 1);
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 0));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 1));
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 1));
- EXPECT_TRUE(bundle->IsEmpty());
-}
-
-TEST(TileBundle, DidBecomeActiveSwapsTiles) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- scoped_refptr<PicturePileImpl> picture_pile =
- FakePicturePileImpl::CreatePile();
-
- scoped_refptr<Tile> tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
- scoped_refptr<Tile> other_tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
-
- scoped_refptr<TileBundle> bundle = tile_manager.CreateTileBundle(0, 0, 2, 2);
- bundle->AddTileAt(ACTIVE_TREE, 0, 0, tile);
- bundle->AddTileAt(PENDING_TREE, 1, 1, other_tile);
-
- EXPECT_EQ(bundle->TileAt(ACTIVE_TREE, 0, 0), tile.get());
- EXPECT_EQ(bundle->TileAt(PENDING_TREE, 1, 1), other_tile.get());
-
- bundle->DidBecomeActive();
-
- EXPECT_EQ(bundle->TileAt(PENDING_TREE, 0, 0), tile.get());
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_EQ(bundle->TileAt(ACTIVE_TREE, 1, 1), other_tile.get());
- EXPECT_FALSE(bundle->TileAt(PENDING_TREE, 1, 1));
-
- bundle->SwapTilesIfRequired();
-
- EXPECT_EQ(bundle->TileAt(PENDING_TREE, 0, 0), tile.get());
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_EQ(bundle->TileAt(ACTIVE_TREE, 1, 1), other_tile.get());
- EXPECT_FALSE(bundle->TileAt(PENDING_TREE, 1, 1));
-}
-
-TEST(TileBundle, DidBecomeRecycledMarksTilesForSwap) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- scoped_refptr<PicturePileImpl> picture_pile =
- FakePicturePileImpl::CreatePile();
-
- scoped_refptr<Tile> tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
- scoped_refptr<Tile> other_tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
-
- scoped_refptr<TileBundle> bundle = tile_manager.CreateTileBundle(0, 0, 2, 2);
- bundle->AddTileAt(ACTIVE_TREE, 0, 0, tile);
- bundle->AddTileAt(PENDING_TREE, 1, 1, other_tile);
-
- EXPECT_EQ(bundle->TileAt(ACTIVE_TREE, 0, 0), tile.get());
- EXPECT_EQ(bundle->TileAt(PENDING_TREE, 1, 1), other_tile.get());
-
- bundle->DidBecomeRecycled();
- bundle->DidBecomeRecycled();
-
- EXPECT_EQ(bundle->TileAt(ACTIVE_TREE, 0, 0), tile.get());
- EXPECT_FALSE(bundle->TileAt(PENDING_TREE, 0, 0));
- EXPECT_EQ(bundle->TileAt(PENDING_TREE, 1, 1), other_tile.get());
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 1, 1));
-
- bundle->DidBecomeRecycled();
- bundle->SwapTilesIfRequired();
-
- EXPECT_EQ(bundle->TileAt(PENDING_TREE, 0, 0), tile.get());
- EXPECT_FALSE(bundle->TileAt(ACTIVE_TREE, 0, 0));
- EXPECT_EQ(bundle->TileAt(ACTIVE_TREE, 1, 1), other_tile.get());
- EXPECT_FALSE(bundle->TileAt(PENDING_TREE, 1, 1));
-}
-
-TEST(TileBundle, EmptyIterator) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- scoped_refptr<TileBundle> bundle = tile_manager.CreateTileBundle(0, 0, 2, 2);
-
- TileBundle::Iterator it(bundle.get());
- EXPECT_FALSE(it);
-
- TileBundle::Iterator active_it(bundle.get(), ACTIVE_TREE);
- EXPECT_FALSE(active_it);
-
- TileBundle::Iterator pending_it(bundle.get(), PENDING_TREE);
- EXPECT_FALSE(pending_it);
-}
-
-TEST(TileBundle, NonEmptyIterator) {
- FakeTileManagerClient tile_manager_client;
- FakeTileManager tile_manager(&tile_manager_client);
- scoped_refptr<PicturePileImpl> picture_pile =
- FakePicturePileImpl::CreatePile();
- scoped_refptr<TileBundle> bundle = tile_manager.CreateTileBundle(0, 0, 2, 2);
-
- scoped_refptr<Tile> tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
- scoped_refptr<Tile> other_tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
- scoped_refptr<Tile> third_tile = tile_manager.CreateTile(picture_pile.get(),
- gfx::Size(256, 256),
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- true);
-
- bundle->AddTileAt(ACTIVE_TREE, 0, 0, tile);
- bundle->AddTileAt(PENDING_TREE, 1, 1, other_tile);
- bundle->AddTileAt(ACTIVE_TREE, 1, 1, third_tile);
-
- TileBundle::Iterator it(bundle.get());
- EXPECT_TRUE(it);
- std::set<Tile*> tiles;
- size_t count = 0;
- while (it) {
- tiles.insert(*it);
- ++it;
- ++count;
- }
-
- EXPECT_EQ(count, tiles.size());
- EXPECT_TRUE(tiles.count(tile.get()));
- EXPECT_TRUE(tiles.count(other_tile.get()));
- EXPECT_TRUE(tiles.count(third_tile.get()));
-
- TileBundle::Iterator active_it(bundle.get(), ACTIVE_TREE);
- EXPECT_TRUE(active_it);
- count = 0;
- tiles.clear();
- while (active_it) {
- tiles.insert(*active_it);
- ++active_it;
- ++count;
- }
-
- EXPECT_EQ(count, tiles.size());
- EXPECT_TRUE(tiles.count(tile.get()));
- EXPECT_FALSE(tiles.count(other_tile.get()));
- EXPECT_TRUE(tiles.count(third_tile.get()));
-
- TileBundle::Iterator pending_it(bundle.get(), PENDING_TREE);
- EXPECT_TRUE(pending_it);
- EXPECT_EQ(*pending_it, other_tile.get());
- ++pending_it;
- EXPECT_FALSE(pending_it);
-}
-
-
-} // namespace
-} // namespace cc
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 17f4525..2fbb6d1 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -224,7 +224,6 @@
global_state_ = GlobalStateThatImpactsTilePriority();
CleanUpReleasedTiles();
- DCHECK_EQ(0u, bundles_.size());
DCHECK_EQ(0u, tiles_.size());
RasterWorkerPool::RasterTask::Queue empty;
@@ -244,35 +243,15 @@
released_tiles_.push_back(tile);
}
-void TileManager::Release(TileBundle* bundle) {
- released_tile_bundles_.push_back(bundle);
-}
-
void TileManager::DidChangeTilePriority(Tile* tile) {
prioritized_tiles_dirty_ = true;
}
-void TileManager::DidChangeTileBundlePriority(TileBundle* bundle) {
- prioritized_tiles_dirty_ = true;
-}
-
bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const {
return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY;
}
void TileManager::CleanUpReleasedTiles() {
- // Clean up bundles first, since they might have tiles that will become
- // released as well.
- for (std::vector<TileBundle*>::iterator it = released_tile_bundles_.begin();
- it != released_tile_bundles_.end();
- ++it) {
- TileBundle* bundle = *it;
- DCHECK(bundles_.find(bundle->id()) != bundles_.end());
- bundles_.erase(bundle->id());
- delete bundle;
- }
- released_tile_bundles_.clear();
-
for (std::vector<Tile*>::iterator it = released_tiles_.begin();
it != released_tiles_.end();
++it) {
@@ -293,6 +272,7 @@
delete tile;
}
+
released_tiles_.clear();
}
@@ -378,130 +358,126 @@
const TreePriority tree_priority = global_state_.tree_priority;
// For each tree, bin into different categories of tiles.
- for (TileBundleMap::iterator bundle_it = bundles_.begin();
- bundle_it != bundles_.end();
- ++bundle_it) {
- for (TileBundle::Iterator it(bundle_it->second); it; ++it) {
- Tile* tile = *it;
- ManagedTileState& mts = tile->managed_state();
+ for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+ Tile* tile = it->second;
+ ManagedTileState& mts = tile->managed_state();
- const ManagedTileState::TileVersion& tile_version =
- tile->GetTileVersionForDrawing();
- bool tile_is_ready_to_draw = tile_version.IsReadyToDraw();
- bool tile_is_active =
- tile_is_ready_to_draw ||
- !mts.tile_versions[mts.raster_mode].raster_task_.is_null();
+ const ManagedTileState::TileVersion& tile_version =
+ tile->GetTileVersionForDrawing();
+ bool tile_is_ready_to_draw = tile_version.IsReadyToDraw();
+ bool tile_is_active =
+ tile_is_ready_to_draw ||
+ !mts.tile_versions[mts.raster_mode].raster_task_.is_null();
- // Get the active priority and bin.
- TilePriority active_priority = it.priority(ACTIVE_TREE);
- ManagedTileBin active_bin = BinFromTilePriority(active_priority);
+ // Get the active priority and bin.
+ TilePriority active_priority = tile->priority(ACTIVE_TREE);
+ ManagedTileBin active_bin = BinFromTilePriority(active_priority);
- // Get the pending priority and bin.
- TilePriority pending_priority = it.priority(PENDING_TREE);
- ManagedTileBin pending_bin = BinFromTilePriority(pending_priority);
+ // Get the pending priority and bin.
+ TilePriority pending_priority = tile->priority(PENDING_TREE);
+ ManagedTileBin pending_bin = BinFromTilePriority(pending_priority);
- bool pending_is_low_res =
- pending_priority.resolution == LOW_RESOLUTION;
- bool pending_is_non_ideal =
- pending_priority.resolution == NON_IDEAL_RESOLUTION;
- bool active_is_non_ideal =
- active_priority.resolution == NON_IDEAL_RESOLUTION;
+ bool pending_is_low_res =
+ pending_priority.resolution == LOW_RESOLUTION;
+ bool pending_is_non_ideal =
+ pending_priority.resolution == NON_IDEAL_RESOLUTION;
+ bool active_is_non_ideal =
+ active_priority.resolution == NON_IDEAL_RESOLUTION;
- // Adjust pending bin state for low res tiles. This prevents
- // pending tree low-res tiles from being initialized before
- // high-res tiles.
- if (pending_is_low_res)
- pending_bin = std::max(pending_bin, EVENTUALLY_BIN);
+ // Adjust pending bin state for low res tiles. This prevents
+ // pending tree low-res tiles from being initialized before
+ // high-res tiles.
+ if (pending_is_low_res)
+ pending_bin = std::max(pending_bin, EVENTUALLY_BIN);
- // Adjust bin state based on if ready to draw.
- active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin];
- pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin];
+ // Adjust bin state based on if ready to draw.
+ active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin];
+ pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin];
- // Adjust bin state based on if active.
- active_bin = kBinIsActiveMap[tile_is_active][active_bin];
- pending_bin = kBinIsActiveMap[tile_is_active][pending_bin];
+ // Adjust bin state based on if active.
+ active_bin = kBinIsActiveMap[tile_is_active][active_bin];
+ pending_bin = kBinIsActiveMap[tile_is_active][pending_bin];
- // We never want to paint new non-ideal tiles, as we always have
- // a high-res tile covering that content (paint that instead).
- if (!tile_is_ready_to_draw && active_is_non_ideal)
- active_bin = NEVER_BIN;
- if (!tile_is_ready_to_draw && pending_is_non_ideal)
- pending_bin = NEVER_BIN;
+ // We never want to paint new non-ideal tiles, as we always have
+ // a high-res tile covering that content (paint that instead).
+ if (!tile_is_ready_to_draw && active_is_non_ideal)
+ active_bin = NEVER_BIN;
+ if (!tile_is_ready_to_draw && pending_is_non_ideal)
+ pending_bin = NEVER_BIN;
- // Compute combined bin.
- ManagedTileBin combined_bin = std::min(active_bin, pending_bin);
+ // Compute combined bin.
+ ManagedTileBin combined_bin = std::min(active_bin, pending_bin);
- ManagedTileBin tree_bin[NUM_TREES];
- tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin];
- tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin];
+ ManagedTileBin tree_bin[NUM_TREES];
+ tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin];
+ tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin];
- // The bin that the tile would have if the GPU memory manager had
- // a maximally permissive policy, send to the GPU memory manager
- // to determine policy.
- ManagedTileBin gpu_memmgr_stats_bin = NEVER_BIN;
- TilePriority tile_priority;
+ // The bin that the tile would have if the GPU memory manager had
+ // a maximally permissive policy, send to the GPU memory manager
+ // to determine policy.
+ ManagedTileBin gpu_memmgr_stats_bin = NEVER_BIN;
+ TilePriority tile_priority;
- switch (tree_priority) {
- case SAME_PRIORITY_FOR_BOTH_TREES:
- mts.bin = kBinPolicyMap[memory_policy][combined_bin];
- gpu_memmgr_stats_bin = combined_bin;
- tile_priority = TilePriority(active_priority, pending_priority);
- break;
- case SMOOTHNESS_TAKES_PRIORITY:
- mts.bin = tree_bin[ACTIVE_TREE];
- gpu_memmgr_stats_bin = active_bin;
- tile_priority = active_priority;
- break;
- case NEW_CONTENT_TAKES_PRIORITY:
- mts.bin = tree_bin[PENDING_TREE];
- gpu_memmgr_stats_bin = pending_bin;
- tile_priority = pending_priority;
- break;
- }
-
- if (!tile_is_ready_to_draw || tile_version.requires_resource()) {
- if ((gpu_memmgr_stats_bin == NOW_BIN) ||
- (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN))
- memory_required_bytes_ += BytesConsumedIfAllocated(tile);
- if (gpu_memmgr_stats_bin != NEVER_BIN)
- memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile);
- }
-
- // Bump up the priority if we determined it's NEVER_BIN on one tree,
- // but is still required on the other tree.
- bool is_in_never_bin_on_both_trees =
- tree_bin[ACTIVE_TREE] == NEVER_BIN &&
- tree_bin[PENDING_TREE] == NEVER_BIN;
-
- if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees)
- mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN;
-
- mts.resolution = tile_priority.resolution;
- mts.time_to_needed_in_seconds = tile_priority.time_to_visible_in_seconds;
- mts.distance_to_visible_in_pixels =
- tile_priority.distance_to_visible_in_pixels;
- mts.required_for_activation = tile_priority.required_for_activation;
-
- mts.visible_and_ready_to_draw =
- tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
-
- if (mts.bin == NEVER_BIN) {
- FreeResourcesForTile(tile);
- continue;
- }
-
- // Note that if the tile is visible_and_ready_to_draw, then we always want
- // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN
- // is something different. The reason for this is that if we're
- // prioritizing the pending tree, we still want visible tiles to take the
- // highest priority.
- ManagedTileBin priority_bin = mts.visible_and_ready_to_draw
- ? NOW_AND_READY_TO_DRAW_BIN
- : mts.bin;
-
- // Insert the tile into a priority set.
- tiles->InsertTile(tile, priority_bin);
+ switch (tree_priority) {
+ case SAME_PRIORITY_FOR_BOTH_TREES:
+ mts.bin = kBinPolicyMap[memory_policy][combined_bin];
+ gpu_memmgr_stats_bin = combined_bin;
+ tile_priority = tile->combined_priority();
+ break;
+ case SMOOTHNESS_TAKES_PRIORITY:
+ mts.bin = tree_bin[ACTIVE_TREE];
+ gpu_memmgr_stats_bin = active_bin;
+ tile_priority = active_priority;
+ break;
+ case NEW_CONTENT_TAKES_PRIORITY:
+ mts.bin = tree_bin[PENDING_TREE];
+ gpu_memmgr_stats_bin = pending_bin;
+ tile_priority = pending_priority;
+ break;
}
+
+ if (!tile_is_ready_to_draw || tile_version.requires_resource()) {
+ if ((gpu_memmgr_stats_bin == NOW_BIN) ||
+ (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN))
+ memory_required_bytes_ += BytesConsumedIfAllocated(tile);
+ if (gpu_memmgr_stats_bin != NEVER_BIN)
+ memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile);
+ }
+
+ // Bump up the priority if we determined it's NEVER_BIN on one tree,
+ // but is still required on the other tree.
+ bool is_in_never_bin_on_both_trees =
+ tree_bin[ACTIVE_TREE] == NEVER_BIN &&
+ tree_bin[PENDING_TREE] == NEVER_BIN;
+
+ if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees)
+ mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN;
+
+ mts.resolution = tile_priority.resolution;
+ mts.time_to_needed_in_seconds = tile_priority.time_to_visible_in_seconds;
+ mts.distance_to_visible_in_pixels =
+ tile_priority.distance_to_visible_in_pixels;
+ mts.required_for_activation = tile_priority.required_for_activation;
+
+ mts.visible_and_ready_to_draw =
+ tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
+
+ if (mts.bin == NEVER_BIN) {
+ FreeResourcesForTile(tile);
+ continue;
+ }
+
+ // Note that if the tile is visible_and_ready_to_draw, then we always want
+ // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN
+ // is something different. The reason for this is that if we're prioritizing
+ // the pending tree, we still want visible tiles to take the highest
+ // priority.
+ ManagedTileBin priority_bin = mts.visible_and_ready_to_draw
+ ? NOW_AND_READY_TO_DRAW_BIN
+ : mts.bin;
+
+ // Insert the tile into a priority set.
+ tiles->InsertTile(tile, priority_bin);
}
}
@@ -983,7 +959,7 @@
}
FreeUnusedResourcesForTile(tile);
- if (tile->is_visible())
+ if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0)
did_initialize_visible_tile_ = true;
}
@@ -1012,14 +988,4 @@
return tile;
}
-scoped_refptr<TileBundle> TileManager::CreateTileBundle(int offset_x,
- int offset_y,
- int width,
- int height) {
- scoped_refptr<TileBundle> bundle = make_scoped_refptr(
- new TileBundle(this, offset_x, offset_y, width, height));
- bundles_[bundle->id()] = bundle;
- return bundle;
-}
-
} // namespace cc
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index 98a66f8..78beb1b 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -21,7 +21,6 @@
#include "cc/resources/raster_worker_pool.h"
#include "cc/resources/resource_pool.h"
#include "cc/resources/tile.h"
-#include "cc/resources/tile_bundle.h"
namespace cc {
class ResourceProvider;
@@ -48,8 +47,7 @@
// by layers; they automatically register with the manager when they are
// created, and unregister from the manager when they are deleted.
class CC_EXPORT TileManager : public RasterWorkerPoolClient,
- public RefCountedManager<Tile>,
- public RefCountedManager<TileBundle> {
+ public RefCountedManager<Tile> {
public:
static scoped_ptr<TileManager> Create(
TileManagerClient* client,
@@ -76,11 +74,6 @@
int source_frame_number,
int flags);
- scoped_refptr<TileBundle> CreateTileBundle(int offset_x,
- int offset_y,
- int width,
- int height);
-
scoped_ptr<base::Value> BasicStateAsValue() const;
scoped_ptr<base::Value> AllTilesAsValue() const;
void GetMemoryStats(size_t* memory_required_bytes,
@@ -131,22 +124,16 @@
size_t max_raster_usage_bytes,
RenderingStatsInstrumentation* rendering_stats_instrumentation);
- // Methods called by Tile and TileBundle
- friend class TileBundle;
+ // Methods called by Tile
friend class Tile;
-
void DidChangeTilePriority(Tile* tile);
- void DidChangeTileBundlePriority(TileBundle* bundle);
void CleanUpReleasedTiles();
- // Overridden from RefCountedManager<Tile>:
+ // Overriden from RefCountedManager<Tile>:
virtual void Release(Tile* tile) OVERRIDE;
- // Overridden from RefCountedManager<TileBundle>:
- virtual void Release(TileBundle* bundle) OVERRIDE;
-
- // Overridden from RasterWorkerPoolClient:
+ // Overriden from RasterWorkerPoolClient:
virtual bool ShouldForceTasksRequiredForActivationToComplete() const
OVERRIDE;
virtual void DidFinishRunningTasks() OVERRIDE;
@@ -198,9 +185,6 @@
typedef base::hash_map<Tile::Id, Tile*> TileMap;
TileMap tiles_;
- typedef base::hash_map<TileBundle::Id, TileBundle*> TileBundleMap;
- TileBundleMap bundles_;
-
PrioritizedTileSet prioritized_tiles_;
bool prioritized_tiles_dirty_;
@@ -232,7 +216,6 @@
RasterTaskCompletionStats update_visible_tiles_stats_;
std::vector<Tile*> released_tiles_;
- std::vector<TileBundle*> released_tile_bundles_;
DISALLOW_COPY_AND_ASSIGN(TileManager);
};
diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc
index 5da12d0..9a651a2 100644
--- a/cc/resources/tile_manager_perftest.cc
+++ b/cc/resources/tile_manager_perftest.cc
@@ -7,7 +7,6 @@
#include "cc/resources/tile_priority.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/fake_tile_manager.h"
#include "cc/test/fake_tile_manager_client.h"
@@ -27,8 +26,8 @@
class TileManagerPerfTest : public testing::Test {
public:
- typedef std::vector<std::pair<scoped_refptr<TileBundle>, ManagedTileBin> >
- TileBundleBinVector;
+ typedef std::vector<std::pair<scoped_refptr<Tile>, ManagedTileBin> >
+ TileBinVector;
TileManagerPerfTest()
: timer_(kWarmupRuns,
@@ -48,8 +47,6 @@
resource_provider_.get(),
raster_task_limit_bytes));
picture_pile_ = FakePicturePileImpl::CreatePile();
- picture_layer_tiling_client_ =
- make_scoped_ptr(new FakePictureLayerTilingClient(tile_manager_.get()));
}
GlobalStateThatImpactsTilePriority GlobalStateForTest() {
@@ -65,7 +62,6 @@
}
virtual void TearDown() OVERRIDE {
- picture_layer_tiling_client_.reset(NULL);
tile_manager_.reset(NULL);
picture_pile_ = NULL;
}
@@ -110,38 +106,30 @@
}
}
- void CreateBinTileBundles(int count,
- ManagedTileBin bin,
- TileBundleBinVector* bundles) {
+ void CreateBinTiles(int count, ManagedTileBin bin, TileBinVector* tiles) {
for (int i = 0; i < count; ++i) {
- scoped_refptr<TileBundle> bundle =
- picture_layer_tiling_client_->CreateTileBundle(0, 0, 2, 2);
- bundle->SetPriority(ACTIVE_TREE, GetTilePriorityFromBin(bin));
- bundle->SetPriority(PENDING_TREE, GetTilePriorityFromBin(bin));
- for (int j = 0; j < 4; ++j) {
- scoped_refptr<Tile> tile =
- tile_manager_->CreateTile(picture_pile_.get(),
- settings_.default_tile_size,
- gfx::Rect(),
- gfx::Rect(),
- 1.0,
- 0,
- 0,
- Tile::USE_LCD_TEXT);
- bundle->AddTileAt(ACTIVE_TREE, j % 2, j / 2, tile);
- bundle->AddTileAt(PENDING_TREE, j % 2, j / 2, tile);
- }
- bundles->push_back(std::make_pair(bundle, bin));
+ scoped_refptr<Tile> tile =
+ tile_manager_->CreateTile(picture_pile_.get(),
+ settings_.default_tile_size,
+ gfx::Rect(),
+ gfx::Rect(),
+ 1.0,
+ 0,
+ 0,
+ Tile::USE_LCD_TEXT);
+ tile->SetPriority(ACTIVE_TREE, GetTilePriorityFromBin(bin));
+ tile->SetPriority(PENDING_TREE, GetTilePriorityFromBin(bin));
+ tiles->push_back(std::make_pair(tile, bin));
}
}
- void CreateBundles(int count, TileBundleBinVector* bundles) {
+ void CreateTiles(int count, TileBinVector* tiles) {
// Roughly an equal amount of all bins.
int count_per_bin = count / NUM_BINS;
- CreateBinTileBundles(count_per_bin, NOW_BIN, bundles);
- CreateBinTileBundles(count_per_bin, SOON_BIN, bundles);
- CreateBinTileBundles(count_per_bin, EVENTUALLY_BIN, bundles);
- CreateBinTileBundles(count - 3 * count_per_bin, NEVER_BIN, bundles);
+ CreateBinTiles(count_per_bin, NOW_BIN, tiles);
+ CreateBinTiles(count_per_bin, SOON_BIN, tiles);
+ CreateBinTiles(count_per_bin, EVENTUALLY_BIN, tiles);
+ CreateBinTiles(count - 3 * count_per_bin, NEVER_BIN, tiles);
}
void RunManageTilesTest(const std::string& test_name,
@@ -150,21 +138,19 @@
DCHECK_GE(tile_count, 100u);
DCHECK_GE(priority_change_percent, 0);
DCHECK_LE(priority_change_percent, 100);
- TileBundleBinVector bundles;
-
- unsigned bundle_count = tile_count / 4;
- CreateBundles(bundle_count, &bundles);
+ TileBinVector tiles;
+ CreateTiles(tile_count, &tiles);
timer_.Reset();
do {
if (priority_change_percent > 0) {
for (unsigned i = 0;
- i < bundle_count;
+ i < tile_count;
i += 100 / priority_change_percent) {
- TileBundle* bundle = bundles[i].first.get();
- ManagedTileBin bin = GetNextBin(bundles[i].second);
- bundle->SetPriority(ACTIVE_TREE, GetTilePriorityFromBin(bin));
- bundle->SetPriority(PENDING_TREE, GetTilePriorityFromBin(bin));
- bundles[i].second = bin;
+ Tile* tile = tiles[i].first.get();
+ ManagedTileBin bin = GetNextBin(tiles[i].second);
+ tile->SetPriority(ACTIVE_TREE, GetTilePriorityFromBin(bin));
+ tile->SetPriority(PENDING_TREE, GetTilePriorityFromBin(bin));
+ tiles[i].second = bin;
}
}
@@ -179,7 +165,6 @@
private:
FakeTileManagerClient tile_manager_client_;
- scoped_ptr<FakePictureLayerTilingClient> picture_layer_tiling_client_;
LayerTreeSettings settings_;
scoped_ptr<FakeTileManager> tile_manager_;
scoped_refptr<FakePicturePileImpl> picture_pile_;
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index fd74c3f..8339bd0 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -67,7 +67,6 @@
}
virtual void TearDown() OVERRIDE {
- bundles_.clear();
tile_manager_.reset(NULL);
picture_pile_ = NULL;
@@ -88,14 +87,9 @@
0,
0,
Tile::USE_LCD_TEXT);
- scoped_refptr<TileBundle> bundle =
- tile_manager_->CreateTileBundle(0, 0, 1, 1);
- bundle->SetPriority(ACTIVE_TREE, active_priority);
- bundle->SetPriority(PENDING_TREE, pending_priority);
- bundle->AddTileAt(ACTIVE_TREE, 0, 0, tile);
- bundle->AddTileAt(PENDING_TREE, 0, 0, tile);
+ tile->SetPriority(ACTIVE_TREE, active_priority);
+ tile->SetPriority(PENDING_TREE, pending_priority);
tiles.push_back(tile);
- bundles_.push_back(bundle);
}
return tiles;
}
@@ -148,7 +142,6 @@
scoped_ptr<ResourceProvider> resource_provider_;
TileMemoryLimitPolicy memory_limit_policy_;
int max_memory_tiles_;
- std::vector<scoped_refptr<TileBundle> > bundles_;
};
TEST_P(TileManagerTest, EnoughMemoryAllowAnything) {
@@ -535,4 +528,3 @@
} // namespace
} // namespace cc
-
diff --git a/cc/test/fake_picture_layer_impl.cc b/cc/test/fake_picture_layer_impl.cc
index b92b807..6e9ffde 100644
--- a/cc/test/fake_picture_layer_impl.cc
+++ b/cc/test/fake_picture_layer_impl.cc
@@ -77,14 +77,14 @@
for (size_t tiling_idx = 0; tiling_idx < tilings_->num_tilings();
++tiling_idx) {
PictureLayerTiling* tiling = tilings_->tiling_at(tiling_idx);
- std::vector<TileBundle*> bundles = tiling->AllTileBundlesForTesting();
- for (size_t bundle_idx = 0; bundle_idx < bundles.size(); ++bundle_idx) {
- TileBundle* bundle = bundles[bundle_idx];
+ std::vector<Tile*> tiles = tiling->AllTilesForTesting();
+ for (size_t tile_idx = 0; tile_idx < tiles.size(); ++tile_idx) {
+ Tile* tile = tiles[tile_idx];
TilePriority priority;
priority.resolution = HIGH_RESOLUTION;
priority.time_to_visible_in_seconds = 0.f;
priority.distance_to_visible_in_pixels = 0.f;
- bundle->SetPriority(tree, priority);
+ tile->SetPriority(tree, priority);
}
}
}
@@ -109,22 +109,15 @@
}
}
-void FakePictureLayerImpl::CreateDefaultTilingsAndTiles(WhichTree tree) {
+void FakePictureLayerImpl::CreateDefaultTilingsAndTiles() {
layer_tree_impl()->UpdateDrawProperties();
if (CanHaveTilings()) {
DCHECK_EQ(tilings()->num_tilings(), 2u);
DCHECK_EQ(tilings()->tiling_at(0)->resolution(), HIGH_RESOLUTION);
DCHECK_EQ(tilings()->tiling_at(1)->resolution(), LOW_RESOLUTION);
- if (tree == ACTIVE_TREE) {
- DCHECK(layer_tree_impl()->IsActiveTree());
- HighResTiling()->CreateTilesForTesting(ACTIVE_TREE);
- LowResTiling()->CreateTilesForTesting(ACTIVE_TREE);
- } else {
- DCHECK(layer_tree_impl()->IsPendingTree());
- HighResTiling()->CreateTilesForTesting(PENDING_TREE);
- LowResTiling()->CreateTilesForTesting(PENDING_TREE);
- }
+ HighResTiling()->CreateAllTilesForTesting();
+ LowResTiling()->CreateAllTilesForTesting();
} else {
DCHECK_EQ(tilings()->num_tilings(), 0u);
}
diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h
index eb1059b..a289934 100644
--- a/cc/test/fake_picture_layer_impl.h
+++ b/cc/test/fake_picture_layer_impl.h
@@ -33,6 +33,7 @@
using PictureLayerImpl::CanHaveTilings;
using PictureLayerImpl::MarkVisibleResourcesAsRequired;
using PictureLayerImpl::DoPostCommitInitializationIfNeeded;
+ using PictureLayerImpl::MinimumContentsScale;
bool needs_post_commit_initialization() const {
return needs_post_commit_initialization_;
@@ -55,7 +56,7 @@
void set_fixed_tile_size(gfx::Size size) { fixed_tile_size_ = size; }
- void CreateDefaultTilingsAndTiles(WhichTree tree);
+ void CreateDefaultTilingsAndTiles();
void SetAllTilesVisible();
void SetAllTilesReady();
void SetAllTilesReadyInTiling(PictureLayerTiling* tiling);
diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc
index c202364..e217336 100644
--- a/cc/test/fake_picture_layer_tiling_client.cc
+++ b/cc/test/fake_picture_layer_tiling_client.cc
@@ -23,14 +23,19 @@
virtual ~FakeInfinitePicturePileImpl() {}
};
-FakePictureLayerTilingClient::FakePictureLayerTilingClient(
- TileManager* tile_manager)
- : tile_manager_(tile_manager),
+FakePictureLayerTilingClient::FakePictureLayerTilingClient()
+ : tile_manager_(new FakeTileManager(&tile_manager_client_)),
pile_(new FakeInfinitePicturePileImpl()),
twin_tiling_(NULL),
- allow_create_tile_(true),
- is_active_(false),
- is_pending_(false) {}
+ allow_create_tile_(true) {}
+
+FakePictureLayerTilingClient::FakePictureLayerTilingClient(
+ ResourceProvider* resource_provider)
+ : tile_manager_(
+ new FakeTileManager(&tile_manager_client_, resource_provider)),
+ pile_(new FakeInfinitePicturePileImpl()),
+ twin_tiling_(NULL),
+ allow_create_tile_(true) {}
FakePictureLayerTilingClient::~FakePictureLayerTilingClient() {
}
@@ -40,18 +45,10 @@
gfx::Rect rect) {
if (!allow_create_tile_)
return scoped_refptr<Tile>();
- return tile_manager()->CreateTile(
+ return tile_manager_->CreateTile(
pile_.get(), tile_size_, rect, gfx::Rect(), 1, 0, 0, Tile::USE_LCD_TEXT);
}
-scoped_refptr<TileBundle> FakePictureLayerTilingClient::CreateTileBundle(
- int offset_x,
- int offset_y,
- int width,
- int height) {
- return tile_manager()->CreateTileBundle(offset_x, offset_y, width, height);
-}
-
void FakePictureLayerTilingClient::SetTileSize(gfx::Size tile_size) {
tile_size_ = tile_size;
}
diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h
index bd4f443..4b092e8 100644
--- a/cc/test/fake_picture_layer_tiling_client.h
+++ b/cc/test/fake_picture_layer_tiling_client.h
@@ -16,16 +16,13 @@
class FakePictureLayerTilingClient : public PictureLayerTilingClient {
public:
- explicit FakePictureLayerTilingClient(TileManager* tile_manager);
+ FakePictureLayerTilingClient();
+ explicit FakePictureLayerTilingClient(ResourceProvider* resource_provider);
virtual ~FakePictureLayerTilingClient();
// PictureLayerTilingClient implementation.
virtual scoped_refptr<Tile> CreateTile(
PictureLayerTiling* tiling, gfx::Rect rect) OVERRIDE;
- virtual scoped_refptr<TileBundle> CreateTileBundle(int offset_x,
- int offset_y,
- int width,
- int height) OVERRIDE;
virtual void UpdatePile(Tile* tile) OVERRIDE {}
virtual gfx::Size CalculateTileSize(
gfx::Size content_bounds) const OVERRIDE;
@@ -45,19 +42,18 @@
void set_invalidation(const Region& region) { invalidation_ = region; }
TileManager* tile_manager() const {
- return tile_manager_;
+ return tile_manager_.get();
}
protected:
- TileManager* tile_manager_;
+ FakeTileManagerClient tile_manager_client_;
+ scoped_ptr<TileManager> tile_manager_;
scoped_refptr<PicturePileImpl> pile_;
gfx::Size tile_size_;
PictureLayerTiling* twin_tiling_;
gfx::Rect text_rect_;
bool allow_create_tile_;
Region invalidation_;
- bool is_active_;
- bool is_pending_;
};
} // namespace cc
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index 907e0fa..6523060 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -55,8 +55,7 @@
make_scoped_ptr<RasterWorkerPool>(new FakeRasterWorkerPool),
1,
std::numeric_limits<unsigned>::max(),
- NULL),
- in_bundle_cleanup_(false) {}
+ NULL) {}
FakeTileManager::FakeTileManager(TileManagerClient* client,
ResourceProvider* resource_provider)
@@ -65,8 +64,7 @@
make_scoped_ptr<RasterWorkerPool>(new FakeRasterWorkerPool),
1,
std::numeric_limits<unsigned>::max(),
- NULL),
- in_bundle_cleanup_(false) {}
+ NULL) {}
FakeTileManager::FakeTileManager(TileManagerClient* client,
ResourceProvider* resource_provider,
@@ -76,8 +74,7 @@
make_scoped_ptr<RasterWorkerPool>(new FakeRasterWorkerPool),
1,
raster_task_limit_bytes,
- NULL),
- in_bundle_cleanup_(false) {}
+ NULL) {}
FakeTileManager::~FakeTileManager() {}
@@ -103,15 +100,7 @@
void FakeTileManager::Release(Tile* tile) {
TileManager::Release(tile);
- if (!in_bundle_cleanup_)
- CleanUpReleasedTiles();
-}
-
-void FakeTileManager::Release(TileBundle* bundle) {
- TileManager::Release(bundle);
- in_bundle_cleanup_ = true;
CleanUpReleasedTiles();
- in_bundle_cleanup_ = false;
}
} // namespace cc
diff --git a/cc/test/fake_tile_manager.h b/cc/test/fake_tile_manager.h
index 032870d..552c0f8 100644
--- a/cc/test/fake_tile_manager.h
+++ b/cc/test/fake_tile_manager.h
@@ -30,13 +30,9 @@
virtual ~FakeTileManager();
virtual void Release(Tile* tile) OVERRIDE;
- virtual void Release(TileBundle* bundle) OVERRIDE;
std::vector<Tile*> tiles_for_raster;
PrioritizedTileSet all_tiles;
-
- private:
- bool in_bundle_cleanup_;
};
} // namespace cc
diff --git a/chrome/VERSION b/chrome/VERSION
index 18930b2..d8eda9a 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
MAJOR=33
MINOR=0
BUILD=1750
-PATCH=16
+PATCH=22
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 01627d9..ce70189 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5591,13 +5591,6 @@
<message name="IDS_FLAGS_FORCE_UNIVERSAL_ACCELERATED_OVERFLOW_SCROLL_MODE_DESCRIPTION" desc="Description of the 'Universal accelerated overflow scroll mode' lab.">
Puts scrolling content in composited layers, even in those cases where promoting the overflow scrolling element to a stacking context and a containing block would have broken stacking or clipping.
</message>
- <message name="IDS_FLAGS_LAYER_SQUASHING_NAME" desc="Name of the 'Layer squashing' lab.">
- Layer squashing
- </message>
- <message name="IDS_FLAGS_LAYER_SQUASHING_DESCRIPTION" desc="Description of the 'layer squashing' lab.">
- Layers that overlap other composited content need to be composited as well, to ensure correct paint order. This feature enables Blink to paint multiple RenderLayer
- subtrees into one composited layer so that we may be able to avoid unnecessarily large number of composited layers.
- </message>
<message name="IDS_FLAGS_ENABLE_DIRECT_WRITE_NAME" desc="Name of the 'Enable DirectWrite' lab.">
Enable DirectWrite
</message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index f90c6cc..c2d3283 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -454,15 +454,6 @@
switches::kDisableUniversalAcceleratedOverflowScroll)
},
{
- "enable-layer-squashing",
- IDS_FLAGS_LAYER_SQUASHING_NAME,
- IDS_FLAGS_LAYER_SQUASHING_DESCRIPTION,
- kOsAll,
- ENABLE_DISABLE_VALUE_TYPE(
- switches::kEnableLayerSquashing,
- switches::kDisableLayerSquashing)
- },
- {
"present-with-GDI",
IDS_FLAGS_PRESENT_WITH_GDI_NAME,
IDS_FLAGS_PRESENT_WITH_GDI_DESCRIPTION,
diff --git a/chrome/browser/chromeos/login/fake_user_manager.cc b/chrome/browser/chromeos/login/fake_user_manager.cc
index 851256a..023a51a 100644
--- a/chrome/browser/chromeos/login/fake_user_manager.cc
+++ b/chrome/browser/chromeos/login/fake_user_manager.cc
@@ -27,11 +27,12 @@
}
}
-void FakeUserManager::AddUser(const std::string& email) {
+const User* FakeUserManager::AddUser(const std::string& email) {
User* user = User::CreateRegularUser(email);
user->set_username_hash(email + kUserIdHashSuffix);
user->SetStubImage(User::kProfileImageIndex, false);
user_list_.push_back(user);
+ return user;
}
void FakeUserManager::AddKioskAppUser(const std::string& kiosk_app_username) {
@@ -44,6 +45,10 @@
UserLoggedIn(email, email + kUserIdHashSuffix, false);
}
+void FakeUserManager::SetProfileForUser(const User* user, Profile* profile) {
+ user_to_profile_[user] = profile;
+}
+
const UserList& FakeUserManager::GetUsers() const {
return user_list_;
}
@@ -173,8 +178,9 @@
}
Profile* FakeUserManager::GetProfileByUser(const User* user) const {
- NOTIMPLEMENTED();
- return NULL;
+ std::map<const User*, Profile*>::const_iterator it =
+ user_to_profile_.find(user);
+ return it == user_to_profile_.end() ? NULL : it->second;
}
base::string16 FakeUserManager::GetUserDisplayName(
diff --git a/chrome/browser/chromeos/login/fake_user_manager.h b/chrome/browser/chromeos/login/fake_user_manager.h
index 4e5d0ea..31ab136 100644
--- a/chrome/browser/chromeos/login/fake_user_manager.h
+++ b/chrome/browser/chromeos/login/fake_user_manager.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_FAKE_USER_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_LOGIN_FAKE_USER_MANAGER_H_
+#include <map>
#include <string>
#include "base/memory/scoped_ptr.h"
@@ -25,7 +26,7 @@
virtual ~FakeUserManager();
// Create and add a new user.
- void AddUser(const std::string& email);
+ const User* AddUser(const std::string& email);
// Create and add a kiosk app user.
void AddKioskAppUser(const std::string& kiosk_app_username);
@@ -33,6 +34,9 @@
// Calculates the user name hash and calls UserLoggedIn to login a user.
void LoginUser(const std::string& email);
+ // Associates |profile| with |user|, for GetProfileByUser().
+ void SetProfileForUser(const User* user, Profile* profile);
+
// UserManager overrides.
virtual const UserList& GetUsers() const OVERRIDE;
virtual UserList GetUsersAdmittedForMultiProfile() const OVERRIDE;
@@ -136,6 +140,7 @@
UserList logged_in_users_;
std::string owner_email_;
User* primary_user_;
+ std::map<const User*, Profile*> user_to_profile_;
// If set this is the active user. If empty, the first created user is the
// active user.
diff --git a/chrome/browser/chromeos/login/multi_profile_user_controller.cc b/chrome/browser/chromeos/login/multi_profile_user_controller.cc
index 1290663..8c3dc8d 100644
--- a/chrome/browser/chromeos/login/multi_profile_user_controller.cc
+++ b/chrome/browser/chromeos/login/multi_profile_user_controller.cc
@@ -11,7 +11,10 @@
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "chrome/browser/chromeos/login/multi_profile_user_controller_delegate.h"
+#include "chrome/browser/chromeos/login/user.h"
#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
@@ -67,9 +70,10 @@
UserManager* user_manager = UserManager::Get();
CHECK(user_manager);
+ const User* primary_user = user_manager->GetPrimaryUser();
std::string primary_user_email;
- if (user_manager->GetPrimaryUser())
- primary_user_email = user_manager->GetPrimaryUser()->email();
+ if (primary_user)
+ primary_user_email = primary_user->email();
// Always allow if there is no primary user or user being checked is the
// primary user.
@@ -80,6 +84,30 @@
if (user_manager->GetOwnerEmail() == user_email)
return false;
+ // Don't allow profiles potentially tainted by data fetched with policy-pushed
+ // certificates to join a multiprofile session.
+ if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(user_email))
+ return false;
+
+ // Don't allow any secondary profiles if the primary profile is tainted.
+ if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(
+ primary_user_email)) {
+ // Check directly in local_state before checking if the primary user has
+ // a PolicyCertService. His profile may have been tainted previously though
+ // he didn't get a PolicyCertService created for this session.
+ return false;
+ }
+
+ // If the primary profile already has policy certificates installed but hasn't
+ // used them yet then it can become tainted at any time during this session;
+ // disable secondary profiles in this case too.
+ Profile* profile =
+ primary_user ? user_manager->GetProfileByUser(primary_user) : NULL;
+ policy::PolicyCertService* service =
+ profile ? policy::PolicyCertServiceFactory::GetForProfile(profile) : NULL;
+ if (service && service->has_policy_certificates())
+ return false;
+
// No user is allowed if the primary user policy forbids it.
const std::string primary_user_behavior = GetCachedValue(primary_user_email);
if (primary_user_behavior == kBehaviorNotAllowed)
@@ -107,11 +135,12 @@
OnUserPrefChanged(user_profile);
}
-void MultiProfileUserController::RemoveCachedValue(
+void MultiProfileUserController::RemoveCachedValues(
const std::string& user_email) {
DictionaryPrefUpdate update(local_state_,
prefs::kCachedMultiProfileUserBehavior);
update->RemoveWithoutPathExpansion(user_email, NULL);
+ policy::PolicyCertServiceFactory::ClearUsedPolicyCertificates(user_email);
}
std::string MultiProfileUserController::GetCachedValue(
diff --git a/chrome/browser/chromeos/login/multi_profile_user_controller.h b/chrome/browser/chromeos/login/multi_profile_user_controller.h
index 0e86e7e..4c1a907 100644
--- a/chrome/browser/chromeos/login/multi_profile_user_controller.h
+++ b/chrome/browser/chromeos/login/multi_profile_user_controller.h
@@ -43,8 +43,8 @@
// Starts to observe the multiprofile user behavior pref of the given profile.
void StartObserving(Profile* user_profile);
- // Removes the cached value for the given user.
- void RemoveCachedValue(const std::string& user_email);
+ // Removes the cached values for the given user.
+ void RemoveCachedValues(const std::string& user_email);
// Possible behavior values.
static const char kBehaviorUnrestricted[];
diff --git a/chrome/browser/chromeos/login/multi_profile_user_controller_unittest.cc b/chrome/browser/chromeos/login/multi_profile_user_controller_unittest.cc
index a5e1a2a..cf4d33b 100644
--- a/chrome/browser/chromeos/login/multi_profile_user_controller_unittest.cc
+++ b/chrome/browser/chromeos/login/multi_profile_user_controller_unittest.cc
@@ -5,10 +5,14 @@
#include "chrome/browser/chromeos/login/multi_profile_user_controller.h"
#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/login/fake_user_manager.h"
#include "chrome/browser/chromeos/login/multi_profile_user_controller_delegate.h"
#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
+#include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/scoped_testing_local_state.h"
@@ -16,6 +20,8 @@
#include "chrome/test/base/testing_pref_service_syncable.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/cert/x509_certificate.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
@@ -78,6 +84,15 @@
},
};
+policy::PolicyCertVerifier* g_policy_cert_verifier_for_factory = NULL;
+
+BrowserContextKeyedService* TestPolicyCertServiceFactory(
+ content::BrowserContext* context) {
+ return policy::PolicyCertService::CreateForTesting(
+ kUsers[0], g_policy_cert_verifier_for_factory, UserManager::Get())
+ .release();
+}
+
} // namespace
class MultiProfileUserControllerTest
@@ -98,13 +113,15 @@
for (size_t i = 0; i < arraysize(kUsers); ++i) {
const std::string user_email(kUsers[i]);
- fake_user_manager_->AddUser(user_email);
+ const User* user = fake_user_manager_->AddUser(user_email);
// Note that user profiles are created after user login in reality.
TestingProfile* user_profile =
profile_manager_.CreateTestingProfile(user_email);
user_profile->set_profile_name(user_email);
user_profiles_.push_back(user_profile);
+
+ fake_user_manager_->SetProfileForUser(user, user_profile);
}
}
@@ -148,7 +165,12 @@
MultiProfileUserController* controller() { return controller_.get(); }
int user_not_allowed_count() const { return user_not_allowed_count_; }
+ TestingProfile* profile(int index) {
+ return user_profiles_[index];
+ }
+
private:
+ content::TestBrowserThreadBundle threads_;
TestingProfileManager profile_manager_;
FakeUserManager* fake_user_manager_; // Not owned
ScopedUserManagerEnabler user_manager_enabler_;
@@ -263,4 +285,75 @@
EXPECT_EQ(1, user_not_allowed_count());
}
+TEST_F(MultiProfileUserControllerTest,
+ UsedPolicyCertificatesAllowedForPrimary) {
+ // Verifies that any user can sign-in as the primary user, regardless of the
+ // tainted state.
+ policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
+ EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0]));
+ EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1]));
+}
+
+TEST_F(MultiProfileUserControllerTest,
+ UsedPolicyCertificatesDisallowedForSecondary) {
+ // Verifies that if a regular user is signed-in then other regular users can
+ // be added but tainted users can't.
+ LoginUser(1);
+ EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0]));
+ policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
+ EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[0]));
+}
+
+TEST_F(MultiProfileUserControllerTest,
+ UsedPolicyCertificatesDisallowsSecondaries) {
+ // Verifies that if a tainted user is signed-in then no other users can
+ // be added.
+ policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
+ LoginUser(0);
+
+ // Double parenthesis to avoid http://en.wikipedia.org/wiki/Most_vexing_parse.
+ policy::PolicyCertVerifier verifier((base::Closure()));
+ g_policy_cert_verifier_for_factory = &verifier;
+ ASSERT_TRUE(
+ policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ profile(0), TestPolicyCertServiceFactory));
+
+ EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1]));
+ policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[1]);
+ EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1]));
+
+ // Flush tasks posted to IO.
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(MultiProfileUserControllerTest,
+ PolicyCertificatesInMemoryDisallowsSecondaries) {
+ // Verifies that if a user is signed-in and has policy certificates installed
+ // then no other users can be added.
+ LoginUser(0);
+
+ // Double parenthesis to avoid http://en.wikipedia.org/wiki/Most_vexing_parse.
+ policy::PolicyCertVerifier verifier((base::Closure()));
+ g_policy_cert_verifier_for_factory = &verifier;
+ ASSERT_TRUE(
+ policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ profile(0), TestPolicyCertServiceFactory));
+ policy::PolicyCertService* service =
+ policy::PolicyCertServiceFactory::GetForProfile(profile(0));
+ ASSERT_TRUE(service);
+
+ EXPECT_FALSE(service->has_policy_certificates());
+ EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1]));
+
+ net::CertificateList certificates;
+ certificates.push_back(new net::X509Certificate(
+ "subject", "issuer", base::Time(), base::Time()));
+ service->OnTrustAnchorsChanged(certificates);
+ EXPECT_TRUE(service->has_policy_certificates());
+ EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1]));
+
+ // Flush tasks posted to IO.
+ base::RunLoop().RunUntilIdle();
+}
+
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
index f3cd10e..c1521cc 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/user_manager_impl.cc
@@ -1380,7 +1380,7 @@
supervised_user_manager_->RemoveNonCryptohomeData(user_id);
- multi_profile_user_controller_->RemoveCachedValue(user_id);
+ multi_profile_user_controller_->RemoveCachedValues(user_id);
}
User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
diff --git a/chrome/browser/chromeos/policy/policy_cert_service.cc b/chrome/browser/chromeos/policy/policy_cert_service.cc
index 990702d..d966fdc 100644
--- a/chrome/browser/chromeos/policy/policy_cert_service.cc
+++ b/chrome/browser/chromeos/policy/policy_cert_service.cc
@@ -7,9 +7,9 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
-#include "base/prefs/pref_service.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
-#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "net/cert/x509_certificate.h"
@@ -21,20 +21,32 @@
}
PolicyCertService::PolicyCertService(
+ const std::string& user_id,
UserNetworkConfigurationUpdater* net_conf_updater,
- PrefService* user_prefs)
+ chromeos::UserManager* user_manager)
: cert_verifier_(NULL),
+ user_id_(user_id),
net_conf_updater_(net_conf_updater),
- user_prefs_(user_prefs),
+ user_manager_(user_manager),
+ has_trust_anchors_(false),
weak_ptr_factory_(this) {
DCHECK(net_conf_updater_);
- DCHECK(user_prefs_);
+ DCHECK(user_manager_);
}
+PolicyCertService::PolicyCertService(const std::string& user_id,
+ PolicyCertVerifier* verifier,
+ chromeos::UserManager* user_manager)
+ : cert_verifier_(verifier),
+ user_id_(user_id),
+ net_conf_updater_(NULL),
+ user_manager_(user_manager),
+ has_trust_anchors_(false),
+ weak_ptr_factory_(this) {}
+
scoped_ptr<PolicyCertVerifier> PolicyCertService::CreatePolicyCertVerifier() {
- base::Closure callback =
- base::Bind(&PolicyCertService::SetUsedPolicyCertificatesOnce,
- weak_ptr_factory_.GetWeakPtr());
+ base::Closure callback = base::Bind(
+ &PolicyCertServiceFactory::SetUsedPolicyCertificates, user_id_);
cert_verifier_ = new PolicyCertVerifier(
base::Bind(base::IgnoreResult(&content::BrowserThread::PostTask),
content::BrowserThread::UI,
@@ -55,6 +67,19 @@
void PolicyCertService::OnTrustAnchorsChanged(
const net::CertificateList& trust_anchors) {
DCHECK(cert_verifier_);
+
+ // Do not use certificates installed via ONC policy if the current session has
+ // multiple profiles. This is important to make sure that any possibly tainted
+ // data is absolutely confined to the managed profile and never, ever leaks to
+ // any other profile.
+ if (!trust_anchors.empty() && user_manager_->GetLoggedInUsers().size() > 1u) {
+ LOG(ERROR) << "Ignoring ONC-pushed certificates update because multiple "
+ << "users are logged in.";
+ return;
+ }
+
+ has_trust_anchors_ = !trust_anchors.empty();
+
// It's safe to use base::Unretained here, because it's guaranteed that
// |cert_verifier_| outlives this object (see description of
// CreatePolicyCertVerifier).
@@ -69,19 +94,24 @@
}
bool PolicyCertService::UsedPolicyCertificates() const {
- return user_prefs_->GetBoolean(prefs::kUsedPolicyCertificatesOnce);
+ return PolicyCertServiceFactory::UsedPolicyCertificates(user_id_);
}
void PolicyCertService::Shutdown() {
weak_ptr_factory_.InvalidateWeakPtrs();
- net_conf_updater_->RemoveTrustedCertsObserver(this);
+ if (net_conf_updater_)
+ net_conf_updater_->RemoveTrustedCertsObserver(this);
OnTrustAnchorsChanged(net::CertificateList());
net_conf_updater_ = NULL;
- user_prefs_ = NULL;
}
-void PolicyCertService::SetUsedPolicyCertificatesOnce() {
- user_prefs_->SetBoolean(prefs::kUsedPolicyCertificatesOnce, true);
+// static
+scoped_ptr<PolicyCertService> PolicyCertService::CreateForTesting(
+ const std::string& user_id,
+ PolicyCertVerifier* verifier,
+ chromeos::UserManager* user_manager) {
+ return make_scoped_ptr(
+ new PolicyCertService(user_id, verifier, user_manager));
}
} // namespace policy
diff --git a/chrome/browser/chromeos/policy/policy_cert_service.h b/chrome/browser/chromeos/policy/policy_cert_service.h
index a32040f..464e89e 100644
--- a/chrome/browser/chromeos/policy/policy_cert_service.h
+++ b/chrome/browser/chromeos/policy/policy_cert_service.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_POLICY_CERT_SERVICE_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_POLICY_CERT_SERVICE_H_
+#include <string>
#include <vector>
#include "base/basictypes.h"
@@ -15,7 +16,9 @@
#include "chrome/browser/chromeos/policy/user_network_configuration_updater.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
-class PrefService;
+namespace chromeos {
+class UserManager;
+}
namespace net {
class X509Certificate;
@@ -35,19 +38,22 @@
: public BrowserContextKeyedService,
public UserNetworkConfigurationUpdater::WebTrustedCertsObserver {
public:
- PolicyCertService(UserNetworkConfigurationUpdater* net_conf_updater,
- PrefService* user_prefs);
+ PolicyCertService(const std::string& user_id,
+ UserNetworkConfigurationUpdater* net_conf_updater,
+ chromeos::UserManager* user_manager);
virtual ~PolicyCertService();
// Creates an associated PolicyCertVerifier. The returned object must only be
// used on the IO thread and must outlive this object.
scoped_ptr<PolicyCertVerifier> CreatePolicyCertVerifier();
- // Returns true if the profile with |user_prefs| has used certificates
+ // Returns true if the profile that owns this service has used certificates
// installed via policy to establish a secure connection before. This means
// that it may have cached content from an untrusted source.
bool UsedPolicyCertificates() const;
+ bool has_policy_certificates() const { return has_trust_anchors_; }
+
// UserNetworkConfigurationUpdater::WebTrustedCertsObserver:
virtual void OnTrustAnchorsChanged(const net::CertificateList& trust_anchors)
OVERRIDE;
@@ -55,12 +61,21 @@
// BrowserContextKeyedService:
virtual void Shutdown() OVERRIDE;
+ static scoped_ptr<PolicyCertService> CreateForTesting(
+ const std::string& user_id,
+ PolicyCertVerifier* verifier,
+ chromeos::UserManager* user_manager);
+
private:
- void SetUsedPolicyCertificatesOnce();
+ PolicyCertService(const std::string& user_id,
+ PolicyCertVerifier* verifier,
+ chromeos::UserManager* user_manager);
PolicyCertVerifier* cert_verifier_;
+ std::string user_id_;
UserNetworkConfigurationUpdater* net_conf_updater_;
- PrefService* user_prefs_;
+ chromeos::UserManager* user_manager_;
+ bool has_trust_anchors_;
// Weak pointers to handle callbacks from PolicyCertVerifier on the IO thread.
// The factory and the created WeakPtrs must only be used on the UI thread.
diff --git a/chrome/browser/chromeos/policy/policy_cert_service_factory.cc b/chrome/browser/chromeos/policy/policy_cert_service_factory.cc
index f0e3d8e..9b5d5f0 100644
--- a/chrome/browser/chromeos/policy/policy_cert_service_factory.cc
+++ b/chrome/browser/chromeos/policy/policy_cert_service_factory.cc
@@ -5,9 +5,15 @@
#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "base/memory/singleton.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/policy/policy_cert_service.h"
#include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
#include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
@@ -38,6 +44,42 @@
return Singleton<PolicyCertServiceFactory>::get();
}
+// static
+void PolicyCertServiceFactory::SetUsedPolicyCertificates(
+ const std::string& user_id) {
+ if (UsedPolicyCertificates(user_id))
+ return;
+ ListPrefUpdate update(g_browser_process->local_state(),
+ prefs::kUsedPolicyCertificates);
+ update->AppendString(user_id);
+}
+
+// static
+void PolicyCertServiceFactory::ClearUsedPolicyCertificates(
+ const std::string& user_id) {
+ ListPrefUpdate update(g_browser_process->local_state(),
+ prefs::kUsedPolicyCertificates);
+ update->Remove(base::StringValue(user_id), NULL);
+}
+
+// static
+bool PolicyCertServiceFactory::UsedPolicyCertificates(
+ const std::string& user_id) {
+ base::StringValue value(user_id);
+ const base::ListValue* list =
+ g_browser_process->local_state()->GetList(prefs::kUsedPolicyCertificates);
+ if (!list) {
+ NOTREACHED();
+ return false;
+ }
+ return list->Find(value) != list->end();
+}
+
+// static
+void PolicyCertServiceFactory::RegisterPrefs(PrefRegistrySimple* local_state) {
+ local_state->RegisterListPref(prefs::kUsedPolicyCertificates);
+}
+
PolicyCertServiceFactory::PolicyCertServiceFactory()
: BrowserContextKeyedServiceFactory(
"PolicyCertService",
@@ -50,15 +92,41 @@
BrowserContextKeyedService* PolicyCertServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
Profile* profile = static_cast<Profile*>(context);
+
+ chromeos::UserManager* user_manager = chromeos::UserManager::Get();
+ chromeos::User* user =
+ user_manager->GetUserByProfile(profile->GetOriginalProfile());
+ if (!user)
+ return NULL;
+
+ // Backwards compatibility: profiles that used policy-pushed certificates used
+ // to have this condition marked in their prefs. This signal has moved to
+ // local_state though, to support checking it before the profile is loaded.
+ // Check the profile here and update the local_state, if appropriate.
+ // TODO(joaodasilva): remove this, eventually.
+ PrefService* prefs = profile->GetOriginalProfile()->GetPrefs();
+ if (prefs->GetBoolean(prefs::kUsedPolicyCertificatesOnce)) {
+ SetUsedPolicyCertificates(user->email());
+ prefs->ClearPref(prefs::kUsedPolicyCertificatesOnce);
+
+ if (user_manager->GetLoggedInUsers().size() > 1u) {
+ // This login should not have been allowed. After rebooting, local_state
+ // will contain the updated list of users that used policy-pushed
+ // certificates and this won't happen again.
+ // Note that a user becomes logged in before his profile is created.
+ LOG(ERROR) << "Shutdown session because a tainted profile was added.";
+ g_browser_process->local_state()->CommitPendingWrite();
+ prefs->CommitPendingWrite();
+ chrome::AttemptUserExit();
+ }
+ }
+
UserNetworkConfigurationUpdater* net_conf_updater =
UserNetworkConfigurationUpdaterFactory::GetForProfile(profile);
if (!net_conf_updater)
return NULL;
- // In case of usage of additional trust anchors from an incognito profile, the
- // prefs of the original profile have to be marked.
- return new PolicyCertService(net_conf_updater,
- profile->GetOriginalProfile()->GetPrefs());
+ return new PolicyCertService(user->email(), net_conf_updater, user_manager);
}
content::BrowserContext* PolicyCertServiceFactory::GetBrowserContextToUse(
@@ -68,6 +136,8 @@
void PolicyCertServiceFactory::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
+ // TODO(joaodasilva): this is used for backwards compatibility.
+ // Remove once it's not necessary anymore.
registry->RegisterBooleanPref(
prefs::kUsedPolicyCertificatesOnce,
false,
diff --git a/chrome/browser/chromeos/policy/policy_cert_service_factory.h b/chrome/browser/chromeos/policy/policy_cert_service_factory.h
index dc945aa..eaa269b 100644
--- a/chrome/browser/chromeos/policy/policy_cert_service_factory.h
+++ b/chrome/browser/chromeos/policy/policy_cert_service_factory.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_POLICY_CERT_SERVICE_FACTORY_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_POLICY_CERT_SERVICE_FACTORY_H_
+#include <string>
+
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
@@ -12,6 +14,7 @@
template <typename T> struct DefaultSingletonTraits;
+class PrefRegistrySimple;
class Profile;
namespace policy {
@@ -37,6 +40,14 @@
static PolicyCertServiceFactory* GetInstance();
+ // Used to mark or clear |user_id| as having used certificates pushed by
+ // policy before.
+ static void SetUsedPolicyCertificates(const std::string& user_id);
+ static void ClearUsedPolicyCertificates(const std::string& user_id);
+ static bool UsedPolicyCertificates(const std::string& user_id);
+
+ static void RegisterPrefs(PrefRegistrySimple* local_state);
+
private:
friend struct DefaultSingletonTraits<PolicyCertServiceFactory>;
diff --git a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc
index b7f8037..fed3c77 100644
--- a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc
+++ b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc
@@ -5,12 +5,10 @@
#include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h"
#include "base/memory/singleton.h"
-#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/login/user.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/policy/user_network_configuration_updater.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/incognito_helpers.h"
@@ -77,14 +75,7 @@
if (user != user_manager->GetPrimaryUser())
return NULL;
- BrowserPolicyConnector* browser_connector =
- g_browser_process->browser_policy_connector();
-
- // Allow trusted certs from policy only for accounts with managed user
- // affiliation, i.e users that are managed by the same domain as the device.
- bool allow_trusted_certs_from_policy =
- browser_connector->GetUserAffiliation(user->email()) ==
- USER_AFFILIATION_MANAGED &&
+ const bool allow_trusted_certs_from_policy =
user->GetType() == chromeos::User::USER_TYPE_REGULAR;
ProfilePolicyConnector* profile_connector =
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc
index ac79ad2..7b4f2a5 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.cc
+++ b/chrome/browser/media/media_capture_devices_dispatcher.cc
@@ -64,12 +64,16 @@
// 1. Virtual keyboard extension.
// 2. Google Voice Search Hotword extension.
// 3. Flutter gesture recognition extension.
+// 4. TODO(smus): Airbender experiment 1.
+// 5. TODO(smus): Airbender experiment 2.
// Once http://crbug.com/292856 is fixed, remove this whitelist.
bool IsMediaRequestWhitelistedForExtension(
const extensions::Extension* extension) {
return extension->id() == "mppnpdlheglhdfmldimlhpnegondlapf" ||
extension->id() == "bepbmhgboaologfdajaanbcjmnhjmhfn" ||
- extension->id() == "jokbpnebhdcladagohdnfgjcpejggllo";
+ extension->id() == "jokbpnebhdcladagohdnfgjcpejggllo" ||
+ extension->id() == "clffjmdilanldobdnedchkdbofoimcgb" ||
+ extension->id() == "nnckehldicaciogcbchegobnafnjkcne";
}
// This is a short-term solution to allow testing of the the Screen Capture API
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 766c330..27dd0e5 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -153,6 +153,7 @@
#include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
#include "chrome/browser/chromeos/policy/device_status_collector.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/chromeos/power/power_prefs.h"
#include "chrome/browser/chromeos/preferences.h"
#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
@@ -305,6 +306,7 @@
policy::AutoEnrollmentClient::RegisterPrefs(registry);
policy::DeviceCloudPolicyManagerChromeOS::RegisterPrefs(registry);
policy::DeviceStatusCollector::RegisterPrefs(registry);
+ policy::PolicyCertServiceFactory::RegisterPrefs(registry);
#endif
#if defined(OS_MACOSX)
diff --git a/chrome/browser/resources/options/manage_profile_overlay.css b/chrome/browser/resources/options/manage_profile_overlay.css
index a1a542b..760030d 100644
--- a/chrome/browser/resources/options/manage_profile_overlay.css
+++ b/chrome/browser/resources/options/manage_profile_overlay.css
@@ -95,18 +95,19 @@
-webkit-margin-end: 10px;
}
-#delete-profile-message,
#delete-managed-profile-addendum {
-webkit-padding-start: 48px;
- background-repeat: no-repeat;
-}
-
-#delete-managed-profile-addendum {
margin-top: 10px;
}
-html[dir='rtl'] #delete-profile-message {
- background-position: right;
+html[dir='ltr'] #delete-profile-icon {
+ float: left;
+ margin-right: 10px;
+}
+
+html[dir='rtl'] #delete-profile-icon {
+ float: right;
+ margin-left: 10px;
}
#create-profile-managed-not-signed-in {
diff --git a/chrome/browser/resources/options/manage_profile_overlay.html b/chrome/browser/resources/options/manage_profile_overlay.html
index 94723c7..42ccfb2 100644
--- a/chrome/browser/resources/options/manage_profile_overlay.html
+++ b/chrome/browser/resources/options/manage_profile_overlay.html
@@ -38,7 +38,10 @@
<div id="manage-profile-overlay-delete" hidden>
<h1 i18n-content="deleteProfileTitle"></h1>
<div class="content-area">
- <div id="delete-profile-message"></div>
+ <div id="delete-profile-message">
+ <img id="delete-profile-icon" class="profile-icon">
+ <div id="delete-profile-text"></div>
+ </div>
<div id="delete-managed-profile-addendum"
i18n-values=".innerHTML:deleteManagedProfileAddendum" hidden>
</div>
diff --git a/chrome/browser/resources/options/manage_profile_overlay.js b/chrome/browser/resources/options/manage_profile_overlay.js
index 35d34df..2d6e64c 100644
--- a/chrome/browser/resources/options/manage_profile_overlay.js
+++ b/chrome/browser/resources/options/manage_profile_overlay.js
@@ -409,10 +409,10 @@
$('manage-profile-overlay-create').hidden = true;
$('manage-profile-overlay-manage').hidden = true;
$('manage-profile-overlay-delete').hidden = false;
- $('delete-profile-message').textContent =
- loadTimeData.getStringF('deleteProfileMessage', profileInfo.name);
- $('delete-profile-message').style.backgroundImage =
+ $('delete-profile-icon').style.content =
imageset(profileInfo.iconURL + '@scalefactorx');
+ $('delete-profile-text').textContent =
+ loadTimeData.getStringF('deleteProfileMessage', profileInfo.name);
$('delete-managed-profile-addendum').hidden = !profileInfo.isManaged;
// Because this dialog isn't useful when refreshing or as part of the
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc
index af3e0e2..458cf24 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -33,12 +33,13 @@
}
void ToolbarButton::Init() {
- SetFocusable(true);
+ SetFocusable(false);
+ SetAccessibilityFocusable(true);
image()->EnableCanvasFlippingForRTLUI(true);
// Provides the hover/pressed style used by buttons in the toolbar.
views::LabelButtonBorder* border =
- new views::LabelButtonBorder(views::Button::STYLE_BUTTON);
+ new views::LabelButtonBorder(views::Button::STYLE_TEXTBUTTON);
const int kHoverImages[] = IMAGE_GRID(IDR_TOOLBAR_BUTTON_HOVER);
border->SetPainter(false, views::Button::STATE_HOVERED,
views::Painter::CreateImageGridPainter(
@@ -47,8 +48,6 @@
border->SetPainter(false, views::Button::STATE_PRESSED,
views::Painter::CreateImageGridPainter(
kPressedImages));
- border->SetPainter(false, views::Button::STATE_NORMAL, NULL);
- border->SetPainter(true, views::Button::STATE_NORMAL, NULL);
set_border(border);
}
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 8483809..5ce98ed 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -90,7 +90,9 @@
"whitelist": [
// http://crbug.com/292856
"3F50C3A83839D9C76334BCE81CDEC06174F266AF",
- "09FDCB5851B8F3378DB630D06E316076E89C95A6"
+ "09FDCB5851B8F3378DB630D06E316076E89C95A6",
+ "39BE69F11F68E4EED080DA3DC2394F7885B7AFF9",
+ "FF78670081967CE21DB86A04AD94A0498F01E20A"
]
}
],
@@ -263,7 +265,7 @@
"extension_types": ["extension", "legacy_packaged_app"]
},
"declarativeContent": {
- "channel": "dev",
+ "channel": "stable",
"extension_types": ["extension"]
},
"declarativeWebRequest": [
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 63ab434..71e8559 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -2259,6 +2259,10 @@
// A boolean pref of the device registered flag (second part after first login).
const char kDeviceRegistered[] = "DeviceRegistered";
+// List of usernames that used certificates pushed by policy before.
+// This is used to prevent these users from joining multiprofile sessions.
+const char kUsedPolicyCertificates[] = "policy.used_policy_certificates";
+
#endif
// Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index d73915f..267c88d 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -776,6 +776,7 @@
extern const char kInitialLocale[];
extern const char kOobeComplete[];
extern const char kDeviceRegistered[];
+extern const char kUsedPolicyCertificates[];
#endif
extern const char kClearPluginLSODataEnabled[];
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index b780de8..edaa35e 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -609,6 +609,10 @@
const gfx::RectF& bounds,
const std::vector<base::string16>& suggestions,
const std::vector<base::string16>& realms) {
+ // Bail if the IPC message is corrupt.
+ if (suggestions.size() != realms.size())
+ return;
+
external_delegate_->OnShowPasswordSuggestions(suggestions,
realms,
field,
@@ -617,6 +621,7 @@
void AutofillManager::OnSetDataList(const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
+ // Bail if the IPC message is corrupt.
if (values.size() != labels.size())
return;
diff --git a/content/browser/aura/gpu_process_transport_factory.cc b/content/browser/aura/gpu_process_transport_factory.cc
index ee92513..38dc904 100644
--- a/content/browser/aura/gpu_process_transport_factory.cc
+++ b/content/browser/aura/gpu_process_transport_factory.cc
@@ -185,6 +185,11 @@
scoped_refptr<ContextProviderCommandBuffer> context_provider;
+ // Software fallback does not happen on Chrome OS.
+#if defined(OS_CHROMEOS)
+ software_fallback = false;
+#endif
+
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kUIEnableSoftwareCompositing) &&
!software_fallback) {
diff --git a/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
index 29df532..041a28d 100644
--- a/content/browser/renderer_host/pepper/pepper_file_io_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
@@ -405,8 +405,10 @@
int32_t PepperFileIOHost::OnHostMsgClose(
ppapi::host::HostMessageContext* context) {
- if (check_quota_)
+ if (check_quota_) {
file_system_host_->CloseQuotaFile(this);
+ check_quota_ = false;
+ }
if (file_ != base::kInvalidPlatformFileValue) {
base::FileUtilProxy::Close(
diff --git a/content/common/gpu/gpu_memory_manager.cc b/content/common/gpu/gpu_memory_manager.cc
index e693627..5dfd3fb 100644
--- a/content/common/gpu/gpu_memory_manager.cc
+++ b/content/common/gpu/gpu_memory_manager.cc
@@ -54,6 +54,7 @@
manage_immediate_scheduled_(false),
max_surfaces_with_frontbuffer_soft_limit_(
max_surfaces_with_frontbuffer_soft_limit),
+ priority_cutoff_(MemoryAllocation::CUTOFF_ALLOW_EVERYTHING),
bytes_available_gpu_memory_(0),
bytes_available_gpu_memory_overridden_(false),
bytes_minimum_per_client_(0),
@@ -68,12 +69,23 @@
{
CommandLine* command_line = CommandLine::ForCurrentProcess();
+ // Use a more conservative memory allocation policy on Linux and Mac because
+ // the platform is unstable when under memory pressure.
+ // http://crbug.com/145600 (Linux)
+ // http://crbug.com/141377 (Mac)
+#if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+ priority_cutoff_ = MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
+#endif
+
#if defined(OS_ANDROID)
bytes_default_per_client_ = 8 * 1024 * 1024;
bytes_minimum_per_client_ = 8 * 1024 * 1024;
#elif defined(OS_CHROMEOS)
bytes_default_per_client_ = 64 * 1024 * 1024;
bytes_minimum_per_client_ = 4 * 1024 * 1024;
+#elif defined(OS_MACOSX)
+ bytes_default_per_client_ = 128 * 1024 * 1024;
+ bytes_minimum_per_client_ = 128 * 1024 * 1024;
#else
bytes_default_per_client_ = 64 * 1024 * 1024;
bytes_minimum_per_client_ = 64 * 1024 * 1024;
@@ -659,16 +671,7 @@
allocation.bytes_limit_when_visible =
client_state->bytes_allocation_when_visible_;
- // Use a more conservative memory allocation policy on Linux and Mac
- // because the platform is unstable when under memory pressure.
- // http://crbug.com/145600 (Linux)
- // http://crbug.com/141377 (Mac)
- allocation.priority_cutoff_when_visible =
-#if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
- MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
-#else
- MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
-#endif
+ allocation.priority_cutoff_when_visible = priority_cutoff_;
client_state->client_->SetMemoryAllocation(allocation);
client_state->client_->SuggestHaveFrontBuffer(!client_state->hibernated_);
diff --git a/content/common/gpu/gpu_memory_manager.h b/content/common/gpu/gpu_memory_manager.h
index a895968..255c20b 100644
--- a/content/common/gpu/gpu_memory_manager.h
+++ b/content/common/gpu/gpu_memory_manager.h
@@ -227,6 +227,9 @@
uint64 max_surfaces_with_frontbuffer_soft_limit_;
+ // The priority cutoff used for all renderers.
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff_;
+
// The maximum amount of memory that may be allocated for GPU resources
uint64 bytes_available_gpu_memory_;
bool bytes_available_gpu_memory_overridden_;
diff --git a/gpu/config/software_rendering_list_json.cc b/gpu/config/software_rendering_list_json.cc
index 08d100f..9af3694 100644
--- a/gpu/config/software_rendering_list_json.cc
+++ b/gpu/config/software_rendering_list_json.cc
@@ -18,7 +18,7 @@
{
"name": "software rendering list",
// Please update the version number whenever you change this file.
- "version": "6.19",
+ "version": "6.20",
"entries": [
{
"id": 1,
@@ -1003,6 +1003,23 @@
"features": [
"all"
]
+ },
+ {
+ "id": 85,
+ "description": "Samsung Gaxlaxy S4 is too buggy to use for video decoding",
+ "cr_bugs": [329072],
+ "os": {
+ "type": "android"
+ },
+ "machine_model": {
+ "name": {
+ "op": "=",
+ "value": "SCH-I545"
+ }
+ },
+ "features": [
+ "accelerated_video_decode"
+ ]
}
]
}
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index fc5b7bf..2df537d 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -163,6 +163,9 @@
void AudioRendererImpl::ResetDecoderDone() {
base::AutoLock auto_lock(lock_);
+ if (state_ == kStopped)
+ return;
+
DCHECK_EQ(state_, kPaused);
DCHECK(!flush_cb_.is_null());
@@ -198,6 +201,7 @@
init_cb_.Reset();
underflow_cb_.Reset();
time_cb_.Reset();
+ flush_cb_.Reset();
}
callback.Run();
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc
index 3878480..5adfbc4 100644
--- a/media/filters/audio_renderer_impl_unittest.cc
+++ b/media/filters/audio_renderer_impl_unittest.cc
@@ -798,4 +798,30 @@
Preroll(1000, PIPELINE_OK);
}
+TEST_F(AudioRendererImplTest, StopDuringFlush) {
+ Initialize();
+
+ Preroll();
+ Play();
+
+ // Partially drain internal buffer so we get a pending read.
+ EXPECT_TRUE(ConsumeBufferedData(frames_buffered() / 2, NULL));
+ WaitForPendingRead();
+
+ Pause();
+
+ EXPECT_TRUE(IsReadPending());
+
+ // Start flushing.
+ WaitableMessageLoopEvent flush_event;
+ renderer_->Flush(flush_event.GetClosure());
+
+ SatisfyPendingRead(kDataSize);
+
+ // Request a Stop() before the flush completes.
+ WaitableMessageLoopEvent stop_event;
+ renderer_->Stop(stop_event.GetClosure());
+ stop_event.RunAndWait();
+}
+
} // namespace media
diff --git a/net/http/transport_security_state_static.h b/net/http/transport_security_state_static.h
index f996c5e..0d127da 100644
--- a/net/http/transport_security_state_static.h
+++ b/net/http/transport_security_state_static.h
@@ -390,7 +390,7 @@
{17, true, "\004goto\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
{18, true, "\005cloud\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
{18, true, "\005glass\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
- {17, true, "\004play\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
+ {17, false, "\004play\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
{20, true, "\006market\007android\003com", true, kGooglePins, DOMAIN_ANDROID_COM },
{26, true, "\003ssl\020google-analytics\003com", true, kGooglePins, DOMAIN_GOOGLE_ANALYTICS_COM },
{18, true, "\005drive\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index f45b8c0..0b9c2ae 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -181,7 +181,8 @@
{ "name": "goto.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "cloud.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "glass.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "play.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ // play.google.com doesn't have include_subdomains because of crbug.com/327834.
+ { "name": "play.google.com", "mode": "force-https", "pins": "google" },
// Other Google-related domains that must use HTTPS.
{ "name": "market.android.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index dbf64af..0c73ec6 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -652,6 +652,14 @@
bool HasPendingAsyncOperation();
bool HasUnhandledReceivedData();
+ // Called on the network task runner.
+ // Causes the associated SSL/TLS session ID to be added to NSS's session
+ // cache, but only if the connection has not been False Started.
+ //
+ // This should only be called after the server's certificate has been
+ // verified, and may not be called within an NSS callback.
+ void CacheSessionIfNecessary();
+
private:
friend class base::RefCountedThreadSafe<Core>;
~Core();
@@ -1274,6 +1282,30 @@
return unhandled_buffer_size_ != 0;
}
+void SSLClientSocketNSS::Core::CacheSessionIfNecessary() {
+ // TODO(rsleevi): This should occur on the NSS task runner, due to the use of
+ // nss_fd_. However, it happens on the network task runner in order to match
+ // the buggy behavior of ExportKeyingMaterial.
+ //
+ // Once http://crbug.com/330360 is fixed, this should be moved to an
+ // implementation that exclusively does this work on the NSS TaskRunner. This
+ // is "safe" because it is only called during the certificate verification
+ // state machine of the main socket, which is safe because no underlying
+ // transport IO will be occuring in that state, and NSS will not be blocking
+ // on any PKCS#11 related locks that might block the Network TaskRunner.
+ DCHECK(OnNetworkTaskRunner());
+
+ // Only cache the session if the connection was not False Started, because
+ // sessions should only be cached *after* the peer's Finished message is
+ // processed.
+ // In the case of False Start, the session will be cached once the
+ // HandshakeCallback is called, which signals the receipt and processing of
+ // the Finished message, and which will happen during a call to
+ // PR_Read/PR_Write.
+ if (!false_started_)
+ SSL_CacheSession(nss_fd_);
+}
+
bool SSLClientSocketNSS::Core::OnNSSTaskRunner() const {
return nss_task_runner_->RunsTasksOnCurrentThread();
}
@@ -1650,7 +1682,17 @@
core->handshake_callback_called_ = true;
if (core->false_started_) {
core->false_started_ = false;
- // If we False Started, DoHandshake already called HandshakeSucceeded.
+ // If the connection was False Started, then at the time of this callback,
+ // the peer's certificate will have been verified or the caller will have
+ // accepted the error.
+ // This is guaranteed when using False Start because this callback will
+ // not be invoked until processing the peer's Finished message, which
+ // will only happen in a PR_Read/PR_Write call, which can only happen
+ // after the peer's certificate is verified.
+ SSL_CacheSessionUnlocked(socket);
+
+ // Additionally, when False Starting, DoHandshake() will have already
+ // called HandshakeSucceeded(), so return now.
return;
}
core->HandshakeSucceeded();
@@ -3519,6 +3561,9 @@
// Only check Certificate Transparency if there were no other errors with
// the connection.
VerifyCT();
+
+ // Only cache the session if the certificate verified successfully.
+ core_->CacheSessionIfNecessary();
}
completed_handshake_ = true;
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 4c426e3..fe62def 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -888,6 +888,7 @@
if (result == OK) {
// TODO(joth): Work out if we need to remember the intermediate CA certs
// when the server sends them to us, and do so here.
+ SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_);
} else {
DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result)
<< " (" << result << ")";
diff --git a/net/socket/ssl_session_cache_openssl.cc b/net/socket/ssl_session_cache_openssl.cc
index f973276..d16bb8d 100644
--- a/net/socket/ssl_session_cache_openssl.cc
+++ b/net/socket/ssl_session_cache_openssl.cc
@@ -24,14 +24,18 @@
class SSLContextExIndex {
public:
SSLContextExIndex() {
- index_ = SSL_CTX_get_ex_new_index(0, 0, 0, 0, 0);
- DCHECK_NE(-1, index_);
+ context_index_ = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+ DCHECK_NE(-1, context_index_);
+ session_index_ = SSL_SESSION_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+ DCHECK_NE(-1, session_index_);
}
- int index() const { return index_; }
+ int context_index() const { return context_index_; }
+ int session_index() const { return session_index_; }
private:
- int index_;
+ int context_index_;
+ int session_index_;
};
// static
@@ -41,7 +45,13 @@
// Retrieve the global EX_DATA index, created lazily on first call, to
// be used with SSL_CTX_set_ex_data() and SSL_CTX_get_ex_data().
static int GetSSLContextExIndex() {
- return s_ssl_context_ex_instance.Get().index();
+ return s_ssl_context_ex_instance.Get().context_index();
+}
+
+// Retrieve the global EX_DATA index, created lazily on first call, to
+// be used with SSL_SESSION_set_ex_data() and SSL_SESSION_get_ex_data().
+static int GetSSLSessionExIndex() {
+ return s_ssl_context_ex_instance.Get().session_index();
}
// Helper struct used to store session IDs in a SessionIdIndex container
@@ -213,6 +223,11 @@
DVLOG(2) << "Lookup session: " << session << " for " << cache_key;
+ void* session_is_good =
+ SSL_SESSION_get_ex_data(session, GetSSLSessionExIndex());
+ if (!session_is_good)
+ return false; // Session has not yet been marked good. Treat as a miss.
+
// Move to front of MRU list.
ordering_.push_front(session);
ordering_.erase(it->second);
@@ -221,6 +236,16 @@
return SSL_set_session(ssl, session) == 1;
}
+ void MarkSSLSessionAsGood(SSL* ssl) {
+ SSL_SESSION* session = SSL_get_session(ssl);
+ if (!session)
+ return;
+
+ // Mark the session as good, allowing it to be used for future connections.
+ SSL_SESSION_set_ex_data(
+ session, GetSSLSessionExIndex(), reinterpret_cast<void*>(1));
+ }
+
// Flush all entries from the cache.
void Flush() {
base::AutoLock lock(lock_);
@@ -474,6 +499,10 @@
return impl_->SetSSLSessionWithKey(ssl, cache_key);
}
+void SSLSessionCacheOpenSSL::MarkSSLSessionAsGood(SSL* ssl) {
+ return impl_->MarkSSLSessionAsGood(ssl);
+}
+
void SSLSessionCacheOpenSSL::Flush() { impl_->Flush(); }
} // namespace net
diff --git a/net/socket/ssl_session_cache_openssl.h b/net/socket/ssl_session_cache_openssl.h
index 4490e0a..bbd9659 100644
--- a/net/socket/ssl_session_cache_openssl.h
+++ b/net/socket/ssl_session_cache_openssl.h
@@ -113,6 +113,14 @@
// Return true iff a cached session was associated with the |ssl| connection.
bool SetSSLSessionWithKey(SSL* ssl, const std::string& cache_key);
+ // Indicates that the SSL session associated with |ssl| is "good" - that is,
+ // that all associated cryptographic parameters that were negotiated,
+ // including the peer's certificate, were successfully validated. Because
+ // OpenSSL does not provide an asynchronous certificate verification
+ // callback, it's necessary to manually manage the sessions to ensure that
+ // only validated sessions are resumed.
+ void MarkSSLSessionAsGood(SSL* ssl);
+
// Flush removes all entries from the cache. This is typically called when
// the system's certificate store has changed.
void Flush();
@@ -130,4 +138,4 @@
} // namespace net
-#endif // NET_SOCKET_SSL_SESSION_CACHE_OPENSSL_H
\ No newline at end of file
+#endif // NET_SOCKET_SSL_SESSION_CACHE_OPENSSL_H
diff --git a/net/socket/ssl_session_cache_openssl_unittest.cc b/net/socket/ssl_session_cache_openssl_unittest.cc
index 8075d34..22c4fba 100644
--- a/net/socket/ssl_session_cache_openssl_unittest.cc
+++ b/net/socket/ssl_session_cache_openssl_unittest.cc
@@ -212,6 +212,9 @@
AddToCache(ssl.get());
EXPECT_EQ(2, session->references);
+ // Mark the session as good, so that it is re-used for the second connection.
+ cache_.MarkSSLSessionAsGood(ssl.get());
+
ssl.reset(NULL);
EXPECT_EQ(1, session->references);
@@ -227,6 +230,7 @@
const std::string key("hello");
ScopedSSL ssl(NewSSL(key));
AddToCache(ssl.get());
+ cache_.MarkSSLSessionAsGood(ssl.get());
ssl.reset(NULL);
ScopedSSL ssl2(NewSSL(key));
@@ -252,6 +256,52 @@
EXPECT_EQ(2, ssl2.get()->session->references);
}
+// Check that when two connections have the same key, a new session is created
+// if the existing session has not yet been marked "good". Further, after the
+// first session completes, if the second session has replaced it in the cache,
+// new sessions should continue to fail until the currently cached session
+// succeeds.
+TEST_F(SSLSessionCacheOpenSSLTest, CheckSessionReplacementWhenNotGood) {
+ const std::string key("hello");
+ ScopedSSL ssl(NewSSL(key));
+
+ // First call should fail because the session is not in the cache.
+ EXPECT_FALSE(cache_.SetSSLSession(ssl.get()));
+ SSL_SESSION* session = ssl.get()->session;
+ ASSERT_TRUE(session);
+ EXPECT_EQ(1, session->references);
+
+ AddToCache(ssl.get());
+ EXPECT_EQ(2, session->references);
+
+ // Second call should find the session ID, but because it is not yet good,
+ // fail to associate it with |ssl2|.
+ ScopedSSL ssl2(NewSSL(key));
+ EXPECT_FALSE(cache_.SetSSLSession(ssl2.get()));
+ SSL_SESSION* session2 = ssl2.get()->session;
+ ASSERT_TRUE(session2);
+ EXPECT_EQ(1, session2->references);
+
+ EXPECT_NE(session, session2);
+
+ // Add the second connection to the cache. It should replace the first
+ // session, and the cache should hold on to the second session.
+ AddToCache(ssl2.get());
+ EXPECT_EQ(1, session->references);
+ EXPECT_EQ(2, session2->references);
+
+ // Mark the first session as good, simulating it completing.
+ cache_.MarkSSLSessionAsGood(ssl.get());
+
+ // Third call should find the session ID, but because the second session (the
+ // current cache entry) is not yet good, fail to associate it with |ssl3|.
+ ScopedSSL ssl3(NewSSL(key));
+ EXPECT_FALSE(cache_.SetSSLSession(ssl3.get()));
+ EXPECT_NE(session, ssl3.get()->session);
+ EXPECT_NE(session2, ssl3.get()->session);
+ EXPECT_EQ(1, ssl3.get()->session->references);
+}
+
TEST_F(SSLSessionCacheOpenSSLTest, CheckEviction) {
const size_t kMaxItems = 20;
int local_id = 1;
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index 06d3e12..8c4e008 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -163,6 +163,16 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=930857
patches/disableticketrenewal.patch
+ * Add explicit functions for managing the SSL/TLS session cache.
+ This is a temporary workaround until Chromium migrates to NSS's
+ asynchronous certificate verification.
+ patches/sessioncache.patch
+
+ * Remove static storage qualifier from variables in sslnonce.c. Due to
+ a clang codegen bug on Mac, this caused an infinite loop.
+ https://code.google.com/p/chromium/issues/detail?id=326011
+ patches/sslnoncestatics.patch
+
Apply the patches to NSS by running the patches/applypatches.sh script. Read
the comments at the top of patches/applypatches.sh for instructions.
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh
index 33850e2..89d97bc 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -81,3 +81,7 @@
patch -p4 < $patches_dir/fallbackscsv.patch
patch -p4 < $patches_dir/disableticketrenewal.patch
+
+patch -p4 < $patches_dir/sessioncache.patch
+
+patch -p4 < $patches_dir/sslnoncestatics.patch
diff --git a/net/third_party/nss/patches/sessioncache.patch b/net/third_party/nss/patches/sessioncache.patch
new file mode 100644
index 0000000..11fd9fc
--- /dev/null
+++ b/net/third_party/nss/patches/sessioncache.patch
@@ -0,0 +1,100 @@
+diff --git a/net/third_party/nss/ssl/exports_win.def b/net/third_party/nss/ssl/exports_win.def
+index e0624f1..a1045bb 100644
+--- a/net/third_party/nss/ssl/exports_win.def
++++ b/net/third_party/nss/ssl/exports_win.def
+@@ -62,3 +62,5 @@ SSL_RestartHandshakeAfterChannelIDReq
+ SSL_GetChannelBinding
+ SSL_PeerSignedCertTimestamps
+ SSL_CipherOrderSet
++SSL_CacheSession
++SSL_CacheSessionUnlocked
+diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+index bef33fc..6f7c988 100644
+--- a/net/third_party/nss/ssl/ssl.h
++++ b/net/third_party/nss/ssl/ssl.h
+@@ -872,6 +872,18 @@ SSL_IMPORT int SSL_DataPending(PRFileDesc *fd);
+ SSL_IMPORT SECStatus SSL_InvalidateSession(PRFileDesc *fd);
+
+ /*
++** Cache the SSL session associated with fd, if it has not already been cached.
++*/
++SSL_IMPORT SECStatus SSL_CacheSession(PRFileDesc *fd);
++
++/*
++** Cache the SSL session associated with fd, if it has not already been cached.
++** This function may only be called when processing within a callback assigned
++** via SSL_HandshakeCallback
++*/
++SSL_IMPORT SECStatus SSL_CacheSessionUnlocked(PRFileDesc *fd);
++
++/*
+ ** Return a SECItem containing the SSL session ID associated with the fd.
+ */
+ SSL_IMPORT SECItem *SSL_GetSessionID(PRFileDesc *fd);
+diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+index 307a0fe..e2be5e6 100644
+--- a/net/third_party/nss/ssl/ssl3con.c
++++ b/net/third_party/nss/ssl/ssl3con.c
+@@ -11240,7 +11240,7 @@ ssl3_FinishHandshake(sslSocket * ss)
+ /* The first handshake is now completed. */
+ ss->handshake = NULL;
+
+- if (ss->ssl3.hs.cacheSID) {
++ if (ss->ssl3.hs.cacheSID && ss->sec.isServer) {
+ (*ss->sec.cache)(ss->sec.ci.sid);
+ ss->ssl3.hs.cacheSID = PR_FALSE;
+ }
+diff --git a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c
+index 31c343f..99538e5 100644
+--- a/net/third_party/nss/ssl/sslsecur.c
++++ b/net/third_party/nss/ssl/sslsecur.c
+@@ -1474,6 +1474,49 @@ SSL_InvalidateSession(PRFileDesc *fd)
+ return rv;
+ }
+
++static void
++ssl3_CacheSessionUnlocked(sslSocket *ss)
++{
++ PORT_Assert(!ss->sec.isServer);
++
++ if (ss->ssl3.hs.cacheSID) {
++ ss->sec.cache(ss->sec.ci.sid);
++ ss->ssl3.hs.cacheSID = PR_FALSE;
++ }
++}
++
++SECStatus
++SSL_CacheSession(PRFileDesc *fd)
++{
++ sslSocket * ss = ssl_FindSocket(fd);
++ SECStatus rv = SECFailure;
++
++ if (ss) {
++ ssl_Get1stHandshakeLock(ss);
++ ssl_GetSSL3HandshakeLock(ss);
++
++ ssl3_CacheSessionUnlocked(ss);
++ rv = SECSuccess;
++
++ ssl_ReleaseSSL3HandshakeLock(ss);
++ ssl_Release1stHandshakeLock(ss);
++ }
++ return rv;
++}
++
++SECStatus
++SSL_CacheSessionUnlocked(PRFileDesc *fd)
++{
++ sslSocket * ss = ssl_FindSocket(fd);
++ SECStatus rv = SECFailure;
++
++ if (ss) {
++ ssl3_CacheSessionUnlocked(ss);
++ rv = SECSuccess;
++ }
++ return rv;
++}
++
+ SECItem *
+ SSL_GetSessionID(PRFileDesc *fd)
+ {
diff --git a/net/third_party/nss/patches/sslnoncestatics.patch b/net/third_party/nss/patches/sslnoncestatics.patch
new file mode 100644
index 0000000..336fe1d
--- /dev/null
+++ b/net/third_party/nss/patches/sslnoncestatics.patch
@@ -0,0 +1,15 @@
+diff --git a/net/third_party/nss/ssl/sslnonce.c b/net/third_party/nss/ssl/sslnonce.c
+index 758aa4e..a3e6e0a 100644
+--- a/net/third_party/nss/ssl/sslnonce.c
++++ b/net/third_party/nss/ssl/sslnonce.c
+@@ -21,8 +21,8 @@
+ PRUint32 ssl_sid_timeout = 100;
+ PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
+
+-static sslSessionID *cache = NULL;
+-static PZLock * cacheLock = NULL;
++sslSessionID *cache = NULL;
++PZLock * cacheLock = NULL;
+
+ /* sids can be in one of 4 states:
+ *
diff --git a/net/third_party/nss/ssl/exports_win.def b/net/third_party/nss/ssl/exports_win.def
index e0624f1..a1045bb 100644
--- a/net/third_party/nss/ssl/exports_win.def
+++ b/net/third_party/nss/ssl/exports_win.def
@@ -62,3 +62,5 @@
SSL_GetChannelBinding
SSL_PeerSignedCertTimestamps
SSL_CipherOrderSet
+SSL_CacheSession
+SSL_CacheSessionUnlocked
diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
index bef33fc..6f7c988 100644
--- a/net/third_party/nss/ssl/ssl.h
+++ b/net/third_party/nss/ssl/ssl.h
@@ -872,6 +872,18 @@
SSL_IMPORT SECStatus SSL_InvalidateSession(PRFileDesc *fd);
/*
+** Cache the SSL session associated with fd, if it has not already been cached.
+*/
+SSL_IMPORT SECStatus SSL_CacheSession(PRFileDesc *fd);
+
+/*
+** Cache the SSL session associated with fd, if it has not already been cached.
+** This function may only be called when processing within a callback assigned
+** via SSL_HandshakeCallback
+*/
+SSL_IMPORT SECStatus SSL_CacheSessionUnlocked(PRFileDesc *fd);
+
+/*
** Return a SECItem containing the SSL session ID associated with the fd.
*/
SSL_IMPORT SECItem *SSL_GetSessionID(PRFileDesc *fd);
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index 307a0fe..e2be5e6 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -11240,7 +11240,7 @@
/* The first handshake is now completed. */
ss->handshake = NULL;
- if (ss->ssl3.hs.cacheSID) {
+ if (ss->ssl3.hs.cacheSID && ss->sec.isServer) {
(*ss->sec.cache)(ss->sec.ci.sid);
ss->ssl3.hs.cacheSID = PR_FALSE;
}
diff --git a/net/third_party/nss/ssl/sslnonce.c b/net/third_party/nss/ssl/sslnonce.c
index 758aa4e..a3e6e0a 100644
--- a/net/third_party/nss/ssl/sslnonce.c
+++ b/net/third_party/nss/ssl/sslnonce.c
@@ -21,8 +21,8 @@
PRUint32 ssl_sid_timeout = 100;
PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
-static sslSessionID *cache = NULL;
-static PZLock * cacheLock = NULL;
+sslSessionID *cache = NULL;
+PZLock * cacheLock = NULL;
/* sids can be in one of 4 states:
*
diff --git a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c
index 31c343f..99538e5 100644
--- a/net/third_party/nss/ssl/sslsecur.c
+++ b/net/third_party/nss/ssl/sslsecur.c
@@ -1474,6 +1474,49 @@
return rv;
}
+static void
+ssl3_CacheSessionUnlocked(sslSocket *ss)
+{
+ PORT_Assert(!ss->sec.isServer);
+
+ if (ss->ssl3.hs.cacheSID) {
+ ss->sec.cache(ss->sec.ci.sid);
+ ss->ssl3.hs.cacheSID = PR_FALSE;
+ }
+}
+
+SECStatus
+SSL_CacheSession(PRFileDesc *fd)
+{
+ sslSocket * ss = ssl_FindSocket(fd);
+ SECStatus rv = SECFailure;
+
+ if (ss) {
+ ssl_Get1stHandshakeLock(ss);
+ ssl_GetSSL3HandshakeLock(ss);
+
+ ssl3_CacheSessionUnlocked(ss);
+ rv = SECSuccess;
+
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_Release1stHandshakeLock(ss);
+ }
+ return rv;
+}
+
+SECStatus
+SSL_CacheSessionUnlocked(PRFileDesc *fd)
+{
+ sslSocket * ss = ssl_FindSocket(fd);
+ SECStatus rv = SECFailure;
+
+ if (ss) {
+ ssl3_CacheSessionUnlocked(ss);
+ rv = SECSuccess;
+ }
+ return rv;
+}
+
SECItem *
SSL_GetSessionID(PRFileDesc *fd)
{
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index b90fecf..fbc90d2 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -44,6 +44,7 @@
#include "net/base/upload_data_stream.h"
#include "net/base/upload_file_element_reader.h"
#include "net/cert/ev_root_ca_metadata.h"
+#include "net/cert/mock_cert_verifier.h"
#include "net/cert/test_root_certs.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store_test_helpers.h"
@@ -6510,6 +6511,104 @@
}
}
+class HTTPSSessionTest : public testing::Test {
+ public:
+ HTTPSSessionTest() : default_context_(true) {
+ cert_verifier_.set_default_result(net::OK);
+
+ default_context_.set_network_delegate(&default_network_delegate_);
+ default_context_.set_cert_verifier(&cert_verifier_);
+ default_context_.Init();
+ }
+ virtual ~HTTPSSessionTest() {}
+
+ protected:
+ MockCertVerifier cert_verifier_;
+ TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest.
+ TestURLRequestContext default_context_;
+};
+
+// Tests that session resumption is not attempted if an invalid certificate
+// is presented.
+TEST_F(HTTPSSessionTest, DontResumeSessionsForInvalidCertificates) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ssl_options.record_resume = true;
+ SpawnedTestServer test_server(
+ SpawnedTestServer::TYPE_HTTPS,
+ ssl_options,
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ ASSERT_TRUE(test_server.Start());
+
+ SSLClientSocket::ClearSessionCache();
+
+ // Simulate the certificate being expired and attempt a connection.
+ cert_verifier_.set_default_result(net::ERR_CERT_DATE_INVALID);
+ {
+ TestDelegate d;
+ URLRequest r(test_server.GetURL("ssl-session-cache"),
+ DEFAULT_PRIORITY,
+ &d,
+ &default_context_);
+
+ r.Start();
+ EXPECT_TRUE(r.is_pending());
+
+ base::RunLoop().Run();
+
+ EXPECT_EQ(1, d.response_started_count());
+ }
+
+ reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())->
+ CloseAllConnections();
+
+ // Now change the certificate to be acceptable (so that the response is
+ // loaded), and ensure that no session id is presented to the peer.
+ cert_verifier_.set_default_result(net::OK);
+ {
+ TestDelegate d;
+ URLRequest r(test_server.GetURL("ssl-session-cache"),
+ DEFAULT_PRIORITY,
+ &d,
+ &default_context_);
+
+ r.Start();
+ EXPECT_TRUE(r.is_pending());
+
+ base::RunLoop().Run();
+
+ // The response will look like;
+ // insert abc
+ // insert xyz
+ //
+ // With a newline at the end which makes the split think that there are
+ // three lines.
+ //
+ // If a session was presented (eg: a bug), then the response would look
+ // like;
+ // insert abc
+ // lookup abc
+ // insert xyz
+
+ EXPECT_EQ(1, d.response_started_count());
+ std::vector<std::string> lines;
+ base::SplitString(d.data_received(), '\n', &lines);
+ ASSERT_EQ(3u, lines.size()) << d.data_received();
+
+ std::string session_id;
+ for (size_t i = 0; i < 2; i++) {
+ std::vector<std::string> parts;
+ base::SplitString(lines[i], '\t', &parts);
+ ASSERT_EQ(2u, parts.size());
+ EXPECT_EQ("insert", parts[0]);
+ if (i == 0) {
+ session_id = parts[1];
+ } else {
+ EXPECT_NE(session_id, parts[1]);
+ }
+ }
+ }
+}
+
class TestSSLConfigService : public SSLConfigService {
public:
TestSSLConfigService(bool ev_enabled,
diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc
index 5ad2bbb..ad07187 100644
--- a/ppapi/proxy/file_io_resource.cc
+++ b/ppapi/proxy/file_io_resource.cc
@@ -18,10 +18,12 @@
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_file_ref_api.h"
+#include "ppapi/thunk/ppb_file_system_api.h"
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_FileIO_API;
using ppapi::thunk::PPB_FileRef_API;
+using ppapi::thunk::PPB_FileSystem_API;
namespace {
@@ -80,11 +82,13 @@
FileIOResource::FileIOResource(Connection connection, PP_Instance instance)
: PluginResource(connection, instance),
- file_system_type_(PP_FILESYSTEMTYPE_INVALID) {
+ file_system_type_(PP_FILESYSTEMTYPE_INVALID),
+ called_close_(false) {
SendCreate(BROWSER, PpapiHostMsg_FileIO_Create());
}
FileIOResource::~FileIOResource() {
+ Close();
}
PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() {
@@ -94,30 +98,36 @@
int32_t FileIOResource::Open(PP_Resource file_ref,
int32_t open_flags,
scoped_refptr<TrackedCallback> callback) {
- EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true);
- if (enter.failed())
+ EnterResourceNoLock<PPB_FileRef_API> enter_file_ref(file_ref, true);
+ if (enter_file_ref.failed())
return PP_ERROR_BADRESOURCE;
- PPB_FileRef_API* file_ref_api = enter.object();
+ PPB_FileRef_API* file_ref_api = enter_file_ref.object();
const FileRefCreateInfo& create_info = file_ref_api->GetCreateInfo();
if (!FileSystemTypeIsValid(create_info.file_system_type)) {
NOTREACHED();
return PP_ERROR_FAILED;
}
-
int32_t rv = state_manager_.CheckOperationState(
FileIOStateManager::OPERATION_EXCLUSIVE, false);
if (rv != PP_OK)
return rv;
file_system_type_ = create_info.file_system_type;
- // Keep the FileSystem host alive by taking a reference to its resource. The
- // FileIO host uses the FileSystem host for running tasks.
- file_system_resource_ = create_info.file_system_plugin_resource;
+
+ if (create_info.file_system_plugin_resource) {
+ EnterResourceNoLock<PPB_FileSystem_API> enter_file_system(
+ create_info.file_system_plugin_resource, true);
+ if (enter_file_system.failed())
+ return PP_ERROR_FAILED;
+ // Take a reference on the FileSystem resource. The FileIO host uses the
+ // FileSystem host for running tasks and checking quota.
+ file_system_resource_ = enter_file_system.resource();
+ }
// Take a reference on the FileRef resource while we're opening the file; we
// don't want the plugin destroying it during the Open operation.
- file_ref_ = enter.resource();
+ file_ref_ = enter_file_ref.resource();
Call<PpapiPluginMsg_FileIO_OpenReply>(BROWSER,
PpapiHostMsg_FileIO_Open(
@@ -279,9 +289,13 @@
}
void FileIOResource::Close() {
- if (file_handle_) {
+ if (called_close_)
+ return;
+
+ called_close_ = true;
+ if (file_handle_)
file_handle_ = NULL;
- }
+
Post(BROWSER, PpapiHostMsg_FileIO_Close());
}
diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h
index ee19848..bfdf24f 100644
--- a/ppapi/proxy/file_io_resource.h
+++ b/ppapi/proxy/file_io_resource.h
@@ -164,7 +164,8 @@
scoped_refptr<FileHandleHolder> file_handle_;
PP_FileSystemType file_system_type_;
- ScopedPPResource file_system_resource_;
+ scoped_refptr<Resource> file_system_resource_;
+ bool called_close_;
FileIOStateManager state_manager_;
scoped_refptr<Resource> file_ref_;
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index 09d2660..51322be 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -56,6 +56,8 @@
layer_brightness_(0.0f),
layer_grayscale_(0.0f),
layer_inverted_(false),
+ layer_mask_(NULL),
+ layer_mask_back_link_(NULL),
zoom_(1),
zoom_inset_(0),
delegate_(NULL),
@@ -78,6 +80,8 @@
layer_brightness_(0.0f),
layer_grayscale_(0.0f),
layer_inverted_(false),
+ layer_mask_(NULL),
+ layer_mask_back_link_(NULL),
zoom_(1),
zoom_inset_(0),
delegate_(NULL),
@@ -96,10 +100,12 @@
animator_ = NULL;
if (compositor_)
compositor_->SetRootLayer(NULL);
- if (layer_mask_.get())
- SetMaskLayer(scoped_ptr<Layer>());
if (parent_)
parent_->Remove(this);
+ if (layer_mask_)
+ SetMaskLayer(NULL);
+ if (layer_mask_back_link_)
+ layer_mask_back_link_->SetMaskLayer(NULL);
for (size_t i = 0; i < children_.size(); ++i)
children_[i]->parent_ = NULL;
cc_layer_->RemoveLayerAnimationEventObserver(this);
@@ -274,18 +280,28 @@
SetLayerFilters();
}
-void Layer::SetMaskLayer(scoped_ptr<Layer> layer_mask) {
+void Layer::SetMaskLayer(Layer* layer_mask) {
// The provided mask should not have a layer mask itself.
- DCHECK(!layer_mask.get() ||
+ DCHECK(!layer_mask ||
(!layer_mask->layer_mask_layer() &&
- layer_mask->children().empty()));
- if (layer_mask_.get() == layer_mask.get())
+ layer_mask->children().empty() &&
+ !layer_mask->layer_mask_back_link_));
+ DCHECK(!layer_mask_back_link_);
+ if (layer_mask_ == layer_mask)
return;
- layer_mask_ = layer_mask.Pass();
+ // We need to de-reference the currently linked object so that no problem
+ // arises if the mask layer gets deleted before this object.
+ if (layer_mask_)
+ layer_mask_->layer_mask_back_link_ = NULL;
+ layer_mask_ = layer_mask;
cc_layer_->SetMaskLayer(
- layer_mask_.get() ? layer_mask_->cc_layer() : NULL);
- if (layer_mask_.get())
- layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor_);
+ layer_mask ? layer_mask->cc_layer() : NULL);
+ // We need to reference the linked object so that it can properly break the
+ // link to us when it gets deleted.
+ if (layer_mask) {
+ layer_mask->layer_mask_back_link_ = this;
+ layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
+ }
}
void Layer::SetBackgroundZoom(float zoom, int inset) {
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index 9ddeb56..0be0d93 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -198,10 +198,11 @@
// Set a layer mask for a layer.
// Note the provided layer mask can neither have a layer mask itself nor can
- // it have any children.
+ // it have any children. The ownership of |layer_mask| will not be
+ // transferred with this call.
// Furthermore: A mask layer can only be set to one layer.
- void SetMaskLayer(scoped_ptr<Layer> layer_mask);
- Layer* layer_mask_layer() { return layer_mask_.get(); }
+ void SetMaskLayer(Layer* layer_mask);
+ Layer* layer_mask_layer() { return layer_mask_; }
// Sets the visibility of the Layer. A Layer may be visible but not
// drawn. This happens if any ancestor of a Layer is not visible.
@@ -448,8 +449,12 @@
float layer_grayscale_;
bool layer_inverted_;
- // The mask layer associated with this layer.
- scoped_ptr<Layer> layer_mask_;
+ // The associated mask layer with this layer.
+ Layer* layer_mask_;
+ // The back link from the mask layer to it's associated masked layer.
+ // We keep this reference for the case that if the mask layer gets deleted
+ // while attached to the main layer before the main layer is deleted.
+ Layer* layer_mask_back_link_;
// The zoom factor to scale the layer by. Zooming is disabled when this is
// set to 1.
diff --git a/ui/views/bubble/tray_bubble_view.cc b/ui/views/bubble/tray_bubble_view.cc
index 9259489..3f947ab 100644
--- a/ui/views/bubble/tray_bubble_view.cc
+++ b/ui/views/bubble/tray_bubble_view.cc
@@ -179,7 +179,7 @@
explicit TrayBubbleContentMask(int corner_radius);
virtual ~TrayBubbleContentMask();
- void set_bounds(gfx::Rect bounds) { bounds_ = bounds; }
+ ui::Layer* layer() { return &layer_; }
// Overridden from LayerDelegate.
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
@@ -187,22 +187,25 @@
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
private:
- gfx::Rect bounds_;
+ ui::Layer layer_;
SkScalar corner_radius_;
DISALLOW_COPY_AND_ASSIGN(TrayBubbleContentMask);
};
TrayBubbleContentMask::TrayBubbleContentMask(int corner_radius)
- : corner_radius_(corner_radius) {
+ : layer_(ui::LAYER_TEXTURED),
+ corner_radius_(corner_radius) {
+ layer_.set_delegate(this);
}
TrayBubbleContentMask::~TrayBubbleContentMask() {
+ layer_.set_delegate(NULL);
}
void TrayBubbleContentMask::OnPaintLayer(gfx::Canvas* canvas) {
SkPath path;
- path.addRoundRect(gfx::RectToSkRect(gfx::Rect(bounds_.size())),
+ path.addRoundRect(gfx::RectToSkRect(gfx::Rect(layer()->bounds().size())),
corner_radius_, corner_radius_);
SkPaint paint;
paint.setAlpha(255);
@@ -337,10 +340,6 @@
TrayBubbleView::~TrayBubbleView() {
mouse_watcher_.reset();
-
- if (layer()->parent()->layer_mask_layer())
- layer()->parent()->layer_mask_layer()->set_delegate(NULL);
-
// Inform host items (models) that their views are being destroyed.
if (delegate_)
delegate_->BubbleViewDestroyed();
@@ -351,11 +350,8 @@
SetAlignment(params_.arrow_alignment);
bubble_border_->UpdateArrowOffset();
- if (get_use_acceleration_when_possible()) {
- scoped_ptr<ui::Layer> mask_layer(new ui::Layer(ui::LAYER_TEXTURED));
- mask_layer->set_delegate(bubble_content_mask_.get());
- layer()->parent()->SetMaskLayer(mask_layer.Pass());
- }
+ if (get_use_acceleration_when_possible())
+ layer()->parent()->SetMaskLayer(bubble_content_mask_->layer());
GetWidget()->Show();
UpdateBubble();
@@ -363,11 +359,8 @@
void TrayBubbleView::UpdateBubble() {
SizeToContents();
- if (get_use_acceleration_when_possible()) {
- bubble_content_mask_->set_bounds(layer()->bounds());
- if (layer()->parent()->layer_mask_layer())
- layer()->parent()->layer_mask_layer()->SetBounds(layer()->bounds());
- }
+ if (get_use_acceleration_when_possible())
+ bubble_content_mask_->layer()->SetBounds(layer()->bounds());
GetWidget()->GetRootView()->SchedulePaint();
}
diff --git a/ui/views/corewm/compound_event_filter.cc b/ui/views/corewm/compound_event_filter.cc
index f5fa2a4..efeca5c 100644
--- a/ui/views/corewm/compound_event_filter.cc
+++ b/ui/views/corewm/compound_event_filter.cc
@@ -72,12 +72,12 @@
// Returns true if the cursor should be hidden on touch events.
bool ShouldHideCursorOnTouch() {
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
+#if defined(OS_CHROMEOS)
return true;
#else
- // Linux Aura does not hide the cursor on touch by default.
- // TODO(tdanderson): Change this if having consistency across
- // all platforms which use Aura is desired.
+ // Not necessary on windows as windows does it for us. If we do need this
+ // funcionality on linux (non-chromeos) we need to make sure
+ // CompoundEventFilter shows on the right root (it currently doesn't always).
return false;
#endif
}
diff --git a/ui/views/corewm/compound_event_filter_unittest.cc b/ui/views/corewm/compound_event_filter_unittest.cc
index 293e2d3..6b852e4 100644
--- a/ui/views/corewm/compound_event_filter_unittest.cc
+++ b/ui/views/corewm/compound_event_filter_unittest.cc
@@ -18,11 +18,11 @@
namespace {
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
+#if defined(OS_CHROMEOS)
base::TimeDelta GetTime() {
return ui::EventTimeForNow();
}
-#endif // defined(OS_CHROMEOS) || defined(OS_WIN)
+#endif // defined(OS_CHROMEOS)
}
@@ -97,10 +97,7 @@
dispatcher()->AsRootWindowHostDelegate()->OnHostMouseEvent(&exit);
EXPECT_FALSE(cursor_client.IsCursorVisible());
}
-#endif // defined(OS_CHROMEOS)
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
-// Touch only hides the cursor on ChromeOS and Windows (crbug.com/322250).
TEST_F(CompoundEventFilterTest, TouchHidesCursor) {
scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter);
aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get());
@@ -148,7 +145,7 @@
EXPECT_FALSE(cursor_client.IsMouseEventsEnabled());
aura::Env::GetInstance()->RemovePreTargetHandler(compound_filter.get());
}
-#endif // defined(OS_CHROMEOS) || defined(OS_WIN)
+#endif // defined(OS_CHROMEOS)
// Tests that if an event filter consumes a gesture, then it doesn't focus the
// window.
diff --git a/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h b/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h
index ff116bc..599b625 100644
--- a/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h
+++ b/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h
@@ -33,7 +33,7 @@
static scoped_ptr<DesktopCursorLoaderUpdater> Create();
// Called when a CursorLoader is created.
- virtual void OnCreate(float device_scale_factor,
+ virtual void OnCreate(aura::RootWindow* window,
ui::CursorLoader* loader) = 0;
// Called when the display has changed (as we may need to reload the cursor
diff --git a/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc b/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc
index f57c694..80d99d1 100644
--- a/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc
+++ b/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc
@@ -53,9 +53,9 @@
DesktopCursorLoaderUpdaterAuraLinux::~DesktopCursorLoaderUpdaterAuraLinux() {}
void DesktopCursorLoaderUpdaterAuraLinux::OnCreate(
- float device_scale_factor,
+ aura::RootWindow* window,
ui::CursorLoader* loader) {
- LoadImageCursors(device_scale_factor, loader);
+ LoadImageCursors(window->compositor()->device_scale_factor(), loader);
}
void DesktopCursorLoaderUpdaterAuraLinux::OnDisplayUpdated(
diff --git a/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h b/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h
index c367518..02db2b2 100644
--- a/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h
+++ b/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h
@@ -17,7 +17,7 @@
virtual ~DesktopCursorLoaderUpdaterAuraLinux();
// Overridden from DesktopCursorLoaderUpdater:
- virtual void OnCreate(float device_scale_factor,
+ virtual void OnCreate(aura::RootWindow* window,
ui::CursorLoader* loader) OVERRIDE;
virtual void OnDisplayUpdated(const gfx::Display& display,
ui::CursorLoader* loader) OVERRIDE;
diff --git a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
index 71bfeca..911f775 100644
--- a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
@@ -11,11 +11,13 @@
namespace views {
DesktopNativeCursorManager::DesktopNativeCursorManager(
+ aura::RootWindow* window,
scoped_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater)
- : cursor_loader_updater_(cursor_loader_updater.Pass()),
+ : root_window_(window),
+ cursor_loader_updater_(cursor_loader_updater.Pass()),
cursor_loader_(ui::CursorLoader::Create()) {
if (cursor_loader_updater_.get())
- cursor_loader_updater_->OnCreate(1.0f, cursor_loader_.get());
+ cursor_loader_updater_->OnCreate(root_window_, cursor_loader_.get());
}
DesktopNativeCursorManager::~DesktopNativeCursorManager() {
@@ -27,15 +29,6 @@
return cursor;
}
-void DesktopNativeCursorManager::AddRootWindow(aura::RootWindow* root_window) {
- root_windows_.insert(root_window);
-}
-
-void DesktopNativeCursorManager::RemoveRootWindow(
- aura::RootWindow* root_window) {
- root_windows_.erase(root_window);
-}
-
void DesktopNativeCursorManager::SetDisplay(
const gfx::Display& display,
views::corewm::NativeCursorManagerDelegate* delegate) {
@@ -55,13 +48,8 @@
cursor_loader_->SetPlatformCursor(&new_cursor);
delegate->CommitCursor(new_cursor);
- if (delegate->IsCursorVisible()) {
- for (RootWindows::const_iterator i = root_windows_.begin();
- i != root_windows_.end();
- ++i) {
- (*i)->SetCursor(new_cursor);
- }
- }
+ if (delegate->IsCursorVisible())
+ root_window_->SetCursor(new_cursor);
}
void DesktopNativeCursorManager::SetVisibility(
@@ -74,18 +62,10 @@
} else {
gfx::NativeCursor invisible_cursor(ui::kCursorNone);
cursor_loader_->SetPlatformCursor(&invisible_cursor);
- for (RootWindows::const_iterator i = root_windows_.begin();
- i != root_windows_.end();
- ++i) {
- (*i)->SetCursor(invisible_cursor);
- }
+ root_window_->SetCursor(invisible_cursor);
}
- for (RootWindows::const_iterator i = root_windows_.begin();
- i != root_windows_.end();
- ++i) {
- (*i)->OnCursorVisibilityChanged(visible);
- }
+ root_window_->OnCursorVisibilityChanged(visible);
}
void DesktopNativeCursorManager::SetCursorSet(
@@ -110,11 +90,7 @@
SetVisibility(delegate->IsCursorVisible(), delegate);
- for (RootWindows::const_iterator i = root_windows_.begin();
- i != root_windows_.end();
- ++i) {
- (*i)->OnMouseEventsEnableStateChanged(enabled);
- }
+ root_window_->OnMouseEventsEnableStateChanged(enabled);
}
} // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
index 18732b0..563131d 100644
--- a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
+++ b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
@@ -5,8 +5,6 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_CURSOR_MANAGER_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_CURSOR_MANAGER_H_
-#include <set>
-
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "ui/views/corewm/native_cursor_manager.h"
@@ -27,25 +25,19 @@
class NativeCursorManagerDelegate;
}
-// A NativeCursorManager that performs the desktop-specific setting of cursor
-// state. Similar to AshNativeCursorManager, it also communicates these changes
-// to all root windows.
+// A NativeCursorManager that interacts with only one RootWindow. (Unlike the
+// one in ash, which interacts with all the RootWindows that ash knows about.)
class VIEWS_EXPORT DesktopNativeCursorManager
: public views::corewm::NativeCursorManager {
public:
DesktopNativeCursorManager(
+ aura::RootWindow* window,
scoped_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater);
virtual ~DesktopNativeCursorManager();
// Builds a cursor and sets the internal platform representation.
gfx::NativeCursor GetInitializedCursor(int type);
- // Adds |root_window| to the set |root_windows_|.
- void AddRootWindow(aura::RootWindow* root_window);
-
- // Removes |root_window| from the set |root_windows_|.
- void RemoveRootWindow(aura::RootWindow* root_window);
-
private:
// Overridden from views::corewm::NativeCursorManager:
virtual void SetDisplay(
@@ -67,10 +59,7 @@
bool enabled,
views::corewm::NativeCursorManagerDelegate* delegate) OVERRIDE;
- // The set of root windows to notify of changes in cursor state.
- typedef std::set<aura::RootWindow*> RootWindows;
- RootWindows root_windows_;
-
+ aura::RootWindow* root_window_;
scoped_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater_;
scoped_ptr<ui::CursorLoader> cursor_loader_;
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 8a008b5..70ba57a 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -200,10 +200,6 @@
////////////////////////////////////////////////////////////////////////////////
// DesktopNativeWidgetAura, public:
-DesktopNativeCursorManager* DesktopNativeWidgetAura::native_cursor_manager_ =
- NULL;
-views::corewm::CursorManager* DesktopNativeWidgetAura::cursor_manager_ = NULL;
-
DesktopNativeWidgetAura::DesktopNativeWidgetAura(
internal::NativeWidgetDelegate* delegate)
: ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
@@ -289,7 +285,7 @@
dispatcher_client_.reset();
aura::client::SetCursorClient(root->window(), NULL);
- native_cursor_manager_->RemoveRootWindow(root);
+ cursor_client_.reset();
aura::client::SetScreenPositionClient(root->window(), NULL);
position_client_.reset();
@@ -385,19 +381,6 @@
// Pass ownership of the filter to the root_window.
root_window_->window()->SetEventFilter(root_window_event_filter_);
- // |root_window_| must be added to |native_cursor_manager_| before
- // OnRootWindowCreated() is called.
- if (!native_cursor_manager_) {
- native_cursor_manager_ = new DesktopNativeCursorManager(
- DesktopCursorLoaderUpdater::Create());
- }
- if (!cursor_manager_) {
- cursor_manager_ = new views::corewm::CursorManager(
- scoped_ptr<corewm::NativeCursorManager>(native_cursor_manager_));
- }
- native_cursor_manager_->AddRootWindow(root_window_.get());
- aura::client::SetCursorClient(root_window_->window(), cursor_manager_);
-
desktop_root_window_host_->OnRootWindowCreated(root_window_.get(), params);
UpdateWindowTransparency();
@@ -415,6 +398,16 @@
aura::client::SetDispatcherClient(root_window_->window(),
dispatcher_client_.get());
+ DesktopNativeCursorManager* desktop_native_cursor_manager =
+ new views::DesktopNativeCursorManager(
+ root_window_.get(),
+ DesktopCursorLoaderUpdater::Create());
+ cursor_client_.reset(
+ new views::corewm::CursorManager(
+ scoped_ptr<corewm::NativeCursorManager>(
+ desktop_native_cursor_manager)));
+ aura::client::SetCursorClient(root_window_->window(), cursor_client_.get());
+
position_client_.reset(new DesktopScreenPositionClient());
aura::client::SetScreenPositionClient(root_window_->window(),
position_client_.get());
@@ -422,7 +415,7 @@
InstallInputMethodEventFilter();
drag_drop_client_ = desktop_root_window_host_->CreateDragDropClient(
- native_cursor_manager_);
+ desktop_native_cursor_manager);
aura::client::SetDragDropClient(root_window_->window(),
drag_drop_client_.get());
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index ca4bca2..494dbc4 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -41,7 +41,6 @@
class DesktopCaptureClient;
class DesktopDispatcherClient;
class DesktopEventClient;
-class DesktopNativeCursorManager;
class DesktopRootWindowHost;
class DropHelper;
class FocusManagerEventHandler;
@@ -78,9 +77,6 @@
corewm::CompoundEventFilter* root_window_event_filter() {
return root_window_event_filter_;
}
- aura::RootWindow* root_window() {
- return root_window_.get();
- }
// Overridden from NativeWidget:
virtual ui::EventHandler* GetEventHandler() OVERRIDE;
@@ -269,6 +265,7 @@
scoped_ptr<aura::client::FocusClient> focus_client_;
scoped_ptr<DesktopDispatcherClient> dispatcher_client_;
+ scoped_ptr<views::corewm::CursorManager> cursor_client_;
scoped_ptr<aura::client::ScreenPositionClient> position_client_;
scoped_ptr<aura::client::DragDropClient> drag_drop_client_;
scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
@@ -295,8 +292,6 @@
bool restore_focus_on_activate_;
gfx::NativeCursor cursor_;
- static views::corewm::CursorManager* cursor_manager_;
- static views::DesktopNativeCursorManager* native_cursor_manager_;
scoped_ptr<corewm::ShadowController> shadow_controller_;
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
index 17a5f97..8390356 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
@@ -4,7 +4,6 @@
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
-#include "ui/aura/client/cursor_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/views/test/views_test_base.h"
@@ -68,95 +67,4 @@
EXPECT_FALSE(widget.GetNativeView()->IsVisible());
}
-// Verify that the cursor state is shared between two native widgets.
-TEST_F(DesktopNativeWidgetAuraTest, GlobalCursorState) {
- // Create two native widgets, each owning different root windows.
- Widget widget_a;
- Widget::InitParams init_params_a =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params_a.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- DesktopNativeWidgetAura* desktop_native_widget_aura_a =
- new DesktopNativeWidgetAura(&widget_a);
- init_params_a.native_widget = desktop_native_widget_aura_a;
- widget_a.Init(init_params_a);
-
- Widget widget_b;
- Widget::InitParams init_params_b =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- init_params_b.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- DesktopNativeWidgetAura* desktop_native_widget_aura_b =
- new DesktopNativeWidgetAura(&widget_b);
- init_params_b.native_widget = desktop_native_widget_aura_b;
- widget_b.Init(init_params_b);
-
- aura::client::CursorClient* cursor_client_a = aura::client::GetCursorClient(
- desktop_native_widget_aura_a->root_window()->window());
- aura::client::CursorClient* cursor_client_b = aura::client::GetCursorClient(
- desktop_native_widget_aura_b->root_window()->window());
-
- // Verify the cursor can be locked using one client and unlocked using
- // another.
- EXPECT_FALSE(cursor_client_a->IsCursorLocked());
- EXPECT_FALSE(cursor_client_b->IsCursorLocked());
-
- cursor_client_a->LockCursor();
- EXPECT_TRUE(cursor_client_a->IsCursorLocked());
- EXPECT_TRUE(cursor_client_b->IsCursorLocked());
-
- cursor_client_b->UnlockCursor();
- EXPECT_FALSE(cursor_client_a->IsCursorLocked());
- EXPECT_FALSE(cursor_client_b->IsCursorLocked());
-
- // Verify that mouse events can be disabled using one client and then
- // re-enabled using another. Note that disabling mouse events should also
- // have the side effect of making the cursor invisible.
- EXPECT_TRUE(cursor_client_a->IsCursorVisible());
- EXPECT_TRUE(cursor_client_b->IsCursorVisible());
- EXPECT_TRUE(cursor_client_a->IsMouseEventsEnabled());
- EXPECT_TRUE(cursor_client_b->IsMouseEventsEnabled());
-
- cursor_client_b->DisableMouseEvents();
- EXPECT_FALSE(cursor_client_a->IsCursorVisible());
- EXPECT_FALSE(cursor_client_b->IsCursorVisible());
- EXPECT_FALSE(cursor_client_a->IsMouseEventsEnabled());
- EXPECT_FALSE(cursor_client_b->IsMouseEventsEnabled());
-
- cursor_client_a->EnableMouseEvents();
- EXPECT_TRUE(cursor_client_a->IsCursorVisible());
- EXPECT_TRUE(cursor_client_b->IsCursorVisible());
- EXPECT_TRUE(cursor_client_a->IsMouseEventsEnabled());
- EXPECT_TRUE(cursor_client_b->IsMouseEventsEnabled());
-
- // Verify that setting the cursor using one cursor client
- // will set it for all root windows.
- EXPECT_EQ(ui::kCursorNone, cursor_client_a->GetCursor().native_type());
- EXPECT_EQ(ui::kCursorNone, cursor_client_b->GetCursor().native_type());
-
- cursor_client_b->SetCursor(ui::kCursorPointer);
- EXPECT_EQ(ui::kCursorPointer, cursor_client_a->GetCursor().native_type());
- EXPECT_EQ(ui::kCursorPointer, cursor_client_b->GetCursor().native_type());
-
- // Verify that hiding the cursor using one cursor client will
- // hide it for all root windows. Note that hiding the cursor
- // should not disable mouse events.
- cursor_client_a->HideCursor();
- EXPECT_FALSE(cursor_client_a->IsCursorVisible());
- EXPECT_FALSE(cursor_client_b->IsCursorVisible());
- EXPECT_TRUE(cursor_client_a->IsMouseEventsEnabled());
- EXPECT_TRUE(cursor_client_b->IsMouseEventsEnabled());
-
- // Verify that the visibility state cannot be changed using one
- // cursor client when the cursor was locked using another.
- cursor_client_b->LockCursor();
- cursor_client_a->ShowCursor();
- EXPECT_FALSE(cursor_client_a->IsCursorVisible());
- EXPECT_FALSE(cursor_client_b->IsCursorVisible());
-
- // Verify the cursor becomes visible on unlock (since a request
- // to make it visible was queued up while the cursor was locked).
- cursor_client_b->UnlockCursor();
- EXPECT_TRUE(cursor_client_a->IsCursorVisible());
- EXPECT_TRUE(cursor_client_b->IsCursorVisible());
-}
-
} // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc
index c258f84..353c3ec 100644
--- a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc
@@ -151,12 +151,6 @@
const Widget::InitParams& params) {
root_window_ = root;
- // The cursor is not necessarily visible when the root window is created.
- aura::client::CursorClient* cursor_client =
- aura::client::GetCursorClient(root_window_->window());
- if (cursor_client)
- is_cursor_visible_ = cursor_client->IsCursorVisible();
-
root_window_->window()->SetProperty(kContentWindowForRootWindow,
content_window_);
root_window_->window()->SetProperty(kDesktopRootWindowHostKey, this);