diff options
author | aelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-28 06:34:44 +0000 |
---|---|---|
committer | aelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-28 06:34:44 +0000 |
commit | 9281fc02ac6c3a3b65b3789694ec52756702dbe1 (patch) | |
tree | d1c78d4305cabae465d83a923670d0ec0acfef53 /cc | |
parent | c9d37ea870d7c541f3622997f5ec0a28382e8f2e (diff) | |
download | chromium_src-9281fc02ac6c3a3b65b3789694ec52756702dbe1.zip chromium_src-9281fc02ac6c3a3b65b3789694ec52756702dbe1.tar.gz chromium_src-9281fc02ac6c3a3b65b3789694ec52756702dbe1.tar.bz2 |
Clamp ScrollbarLayer's texture size to GL_MAX_TEXTURE_SIZE.
When a scale transformation is applied to a scrollbar, its texture size
can be larger than the GL maximum. Limit the value of contentsScale to
avoid this.
Picked up from original patch at https://codereview.chromium.org/11419140/
BUG=161029
Review URL: https://chromiumcodereview.appspot.com/11428042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@169869 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/contents_scaling_layer.cc | 6 | ||||
-rw-r--r-- | cc/contents_scaling_layer.h | 2 | ||||
-rw-r--r-- | cc/resource_provider.cc | 3 | ||||
-rw-r--r-- | cc/scrollbar_layer.cc | 28 | ||||
-rw-r--r-- | cc/scrollbar_layer.h | 4 | ||||
-rw-r--r-- | cc/scrollbar_layer_unittest.cc | 57 |
6 files changed, 99 insertions, 1 deletions
diff --git a/cc/contents_scaling_layer.cc b/cc/contents_scaling_layer.cc index b758bd3..454b6e7 100644 --- a/cc/contents_scaling_layer.cc +++ b/cc/contents_scaling_layer.cc @@ -7,6 +7,10 @@ namespace cc { +gfx::Size ContentsScalingLayer::computeContentBoundsForScale(float scaleX, float scaleY) const { + return gfx::ToCeiledSize(gfx::ScaleSize(bounds(), scaleX, scaleY)); +} + ContentsScalingLayer::ContentsScalingLayer() : m_contentsScale(1.0) { } @@ -15,7 +19,7 @@ ContentsScalingLayer::~ContentsScalingLayer() { } gfx::Size ContentsScalingLayer::contentBounds() const { - return gfx::ToCeiledSize(gfx::ScaleSize(bounds(), contentsScaleX(), contentsScaleY())); + return computeContentBoundsForScale(contentsScaleX(), contentsScaleY()); } float ContentsScalingLayer::contentsScaleX() const { diff --git a/cc/contents_scaling_layer.h b/cc/contents_scaling_layer.h index af79472..4f0fcdb 100644 --- a/cc/contents_scaling_layer.h +++ b/cc/contents_scaling_layer.h @@ -23,6 +23,8 @@ class CC_EXPORT ContentsScalingLayer : public Layer { ContentsScalingLayer(); virtual ~ContentsScalingLayer(); + gfx::Size computeContentBoundsForScale(float scaleX, float scaleY) const; + private: float m_contentsScale; }; diff --git a/cc/resource_provider.cc b/cc/resource_provider.cc index 2759d1a..9f208af 100644 --- a/cc/resource_provider.cc +++ b/cc/resource_provider.cc @@ -154,6 +154,9 @@ ResourceProvider::ResourceId ResourceProvider::createResource(int pool, const gf ResourceProvider::ResourceId ResourceProvider::createGLTexture(int pool, const gfx::Size& size, GLenum format, TextureUsageHint hint) { + DCHECK_LE(size.width(), m_maxTextureSize); + DCHECK_LE(size.height(), m_maxTextureSize); + DCHECK(m_threadChecker.CalledOnValidThread()); unsigned textureId = 0; WebGraphicsContext3D* context3d = m_context->context3D(); diff --git a/cc/scrollbar_layer.cc b/cc/scrollbar_layer.cc index 392369f..09c4e7f 100644 --- a/cc/scrollbar_layer.cc +++ b/cc/scrollbar_layer.cc @@ -40,6 +40,32 @@ ScrollbarLayer::~ScrollbarLayer() { } +int ScrollbarLayer::maxTextureSize() { + DCHECK(layerTreeHost()); + return layerTreeHost()->rendererCapabilities().maxTextureSize; +} + +float ScrollbarLayer::clampScaleToMaxTextureSize(float scale) { + // If the scaled contentBounds() is bigger than the max texture size of the + // device, we need to clamp it by rescaling, since contentBounds() is used + // below to set the texture size. + gfx::Size scaledBounds = computeContentBoundsForScale(scale, scale); + if (scaledBounds.width() > maxTextureSize() || scaledBounds.height() > maxTextureSize()) { + if (scaledBounds.width() > scaledBounds.height()) + return (maxTextureSize() - 1) / static_cast<float>(bounds().width()); + else + return (maxTextureSize() - 1) / static_cast<float>(bounds().height()); + } + return scale; +} + +void ScrollbarLayer::setContentsScale(float contentsScale) { + contentsScale = clampScaleToMaxTextureSize(contentsScale); + ContentsScalingLayer::setContentsScale(contentsScale); + DCHECK_LE(contentBounds().width(), maxTextureSize()); + DCHECK_LE(contentBounds().height(), maxTextureSize()); +} + void ScrollbarLayer::pushPropertiesTo(LayerImpl* layer) { ContentsScalingLayer::pushPropertiesTo(layer); @@ -235,6 +261,8 @@ void ScrollbarLayer::setTexturePriorities(const PriorityCalculator&) { if (contentBounds().IsEmpty()) return; + DCHECK_LE(contentBounds().width(), maxTextureSize()); + DCHECK_LE(contentBounds().height(), maxTextureSize()); createUpdaterIfNeeded(); diff --git a/cc/scrollbar_layer.h b/cc/scrollbar_layer.h index dcadfc2..6101dfb 100644 --- a/cc/scrollbar_layer.h +++ b/cc/scrollbar_layer.h @@ -30,6 +30,7 @@ public: virtual void update(ResourceUpdateQueue&, const OcclusionTracker*, RenderingStats&) OVERRIDE; virtual void setLayerTreeHost(LayerTreeHost*) OVERRIDE; virtual void pushPropertiesTo(LayerImpl*) OVERRIDE; + virtual void setContentsScale(float contentsScale) OVERRIDE; int scrollLayerId() const { return m_scrollLayerId; } void setScrollLayerId(int id) { m_scrollLayerId = id; } @@ -45,6 +46,9 @@ private: void createUpdaterIfNeeded(); gfx::Rect scrollbarLayerRectToContentRect(const gfx::Rect& layerRect) const; + int maxTextureSize(); + float clampScaleToMaxTextureSize(float scale); + scoped_ptr<WebKit::WebScrollbar> m_scrollbar; WebKit::WebScrollbarThemePainter m_painter; scoped_ptr<WebKit::WebScrollbarThemeGeometry> m_geometry; diff --git a/cc/scrollbar_layer_unittest.cc b/cc/scrollbar_layer_unittest.cc index b01ec88..275f98b 100644 --- a/cc/scrollbar_layer_unittest.cc +++ b/cc/scrollbar_layer_unittest.cc @@ -8,6 +8,7 @@ #include "cc/scrollbar_layer_impl.h" #include "cc/single_thread_proxy.h" #include "cc/test/fake_web_scrollbar_theme_geometry.h" +#include "cc/test/layer_tree_test_common.h" #include "cc/tree_synchronizer.h" #include "testing/gtest/include/gtest/gtest.h" #include <public/WebScrollbar.h> @@ -121,5 +122,61 @@ TEST(ScrollbarLayerTest, scrollOffsetSynchronization) EXPECT_EQ(300, ccScrollbarLayer->maximum()); } +class ScrollbarLayerTestMaxTextureSize : public WebKitTests::ThreadedTest { +public: + ScrollbarLayerTestMaxTextureSize() {} + + void setScrollbarBounds(gfx::Size bounds) { + m_bounds = bounds; + } + + virtual void beginTest() OVERRIDE + { + scoped_ptr<WebKit::WebScrollbar> scrollbar(FakeWebScrollbar::create()); + m_scrollbarLayer = ScrollbarLayer::create(scrollbar.Pass(), m_painter, WebKit::FakeWebScrollbarThemeGeometry::create(), 1); + m_scrollbarLayer->setBounds(m_bounds); + m_layerTreeHost->rootLayer()->addChild(m_scrollbarLayer); + + m_scrollLayer = Layer::create(); + m_scrollbarLayer->setScrollLayerId(m_scrollLayer->id()); + m_layerTreeHost->rootLayer()->addChild(m_scrollLayer); + + postSetNeedsCommitToMainThread(); + } + + virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE + { + m_layerTreeHost->initializeRendererIfNeeded(); + + const int kMaxTextureSize = m_layerTreeHost->rendererCapabilities().maxTextureSize; + + // Check first that we're actually testing something. + EXPECT_GT(m_scrollbarLayer->bounds().width(), kMaxTextureSize); + + EXPECT_EQ(m_scrollbarLayer->contentBounds().width(), kMaxTextureSize - 1); + EXPECT_EQ(m_scrollbarLayer->contentBounds().height(), kMaxTextureSize - 1); + + endTest(); + } + + virtual void afterTest() OVERRIDE + { + } + +private: + scoped_refptr<ScrollbarLayer> m_scrollbarLayer; + scoped_refptr<Layer> m_scrollLayer; + WebKit::WebScrollbarThemePainter m_painter; + gfx::Size m_bounds; +}; + +TEST_F(ScrollbarLayerTestMaxTextureSize, runTest) { + WebKit::FakeWebGraphicsContext3D context; + int max_size = 0; + context.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); + setScrollbarBounds(gfx::Size(max_size + 100, max_size + 100)); + runTest(true); +} + } // namespace } // namespace cc |