summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authoraelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-28 06:34:44 +0000
committeraelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-28 06:34:44 +0000
commit9281fc02ac6c3a3b65b3789694ec52756702dbe1 (patch)
treed1c78d4305cabae465d83a923670d0ec0acfef53 /cc
parentc9d37ea870d7c541f3622997f5ec0a28382e8f2e (diff)
downloadchromium_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.cc6
-rw-r--r--cc/contents_scaling_layer.h2
-rw-r--r--cc/resource_provider.cc3
-rw-r--r--cc/scrollbar_layer.cc28
-rw-r--r--cc/scrollbar_layer.h4
-rw-r--r--cc/scrollbar_layer_unittest.cc57
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