diff options
author | whunt@chromium.org <whunt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-13 02:42:19 +0000 |
---|---|---|
committer | whunt@chromium.org <whunt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-13 02:42:19 +0000 |
commit | cd48d688a68cb5136b223eac6ae85cf2b849059e (patch) | |
tree | 7655038174905aea7b212b53add335c8c94ab5d0 /cc | |
parent | e71af8797e057e987e8b689f1d4230de8a18f299 (diff) | |
download | chromium_src-cd48d688a68cb5136b223eac6ae85cf2b849059e.zip chromium_src-cd48d688a68cb5136b223eac6ae85cf2b849059e.tar.gz chromium_src-cd48d688a68cb5136b223eac6ae85cf2b849059e.tar.bz2 |
explicitly validating assumptions about positive matrix scale
Due to my lack of git know-how this ended up being the entire clipping patch plus my last validation rather than just a few line fix.
Given that the last one got reverted as a test anyway perhaps this is just as well?
BUG=165237
Review URL: https://chromiumcodereview.appspot.com/11481004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172788 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/texture_draw_quad.cc | 48 | ||||
-rw-r--r-- | cc/texture_draw_quad.h | 2 | ||||
-rw-r--r-- | cc/texture_layer_impl.cc | 7 |
3 files changed, 56 insertions, 1 deletions
diff --git a/cc/texture_draw_quad.cc b/cc/texture_draw_quad.cc index d552c39..5ad73b6 100644 --- a/cc/texture_draw_quad.cc +++ b/cc/texture_draw_quad.cc @@ -58,4 +58,52 @@ const TextureDrawQuad* TextureDrawQuad::MaterialCast( return static_cast<const TextureDrawQuad*>(quad); } +bool TextureDrawQuad::PerformClipping() { + // This only occurs if the rect is only scaled and translated (and thus still + // axis aligned). + if (!quadTransform().IsScaleOrTranslation()) + return false; + + // Grab our scale and make sure it's positive. + float x_scale = quadTransform().matrix().getDouble(0,0); + float y_scale = quadTransform().matrix().getDouble(1,1); + if (x_scale <= 0.0f || y_scale <= 0.0f) + return false; + + // Grab our offset. + gfx::Vector2dF offset( + quadTransform().matrix().getDouble(0,3), + quadTransform().matrix().getDouble(1,3)); + + // Transform the rect by the scale and offset. + gfx::RectF rectF = rect; + rectF.Scale(x_scale, y_scale); + rectF += offset; + + // Perform clipping and check to see if the result is empty. + gfx::RectF clippedRect = IntersectRects(rectF, clipRect()); + if (clippedRect.IsEmpty()) { + rect = gfx::Rect(); + uv_rect = gfx::RectF(); + return true; + } + + // Create a new uv-rect by clipping the old one to the new bounds. + uv_rect = gfx::RectF( + uv_rect.x()+uv_rect.width ()/rectF.width ()*(clippedRect.x()-rectF.x()), + uv_rect.y()+uv_rect.height()/rectF.height()*(clippedRect.y()-rectF.y()), + uv_rect.width () / rectF.width () * clippedRect.width (), + uv_rect.height() / rectF.height() * clippedRect.height()); + + // Move the clipped rectangle back into its space. + clippedRect -= offset; + clippedRect.Scale(1.0f / x_scale, 1.0f / y_scale); + rect = gfx::Rect( + static_cast<int>(clippedRect.x() + 0.5f), + static_cast<int>(clippedRect.y() + 0.5f), + static_cast<int>(clippedRect.width() + 0.5f), + static_cast<int>(clippedRect.height() + 0.5f)); + return true; +} + } // namespace cc diff --git a/cc/texture_draw_quad.h b/cc/texture_draw_quad.h index 177febf..6ae0e57 100644 --- a/cc/texture_draw_quad.h +++ b/cc/texture_draw_quad.h @@ -40,6 +40,8 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { bool flipped; static const TextureDrawQuad* MaterialCast(const DrawQuad*); + + bool PerformClipping(); private: TextureDrawQuad(); }; diff --git a/cc/texture_layer_impl.cc b/cc/texture_layer_impl.cc index 7fcfe43..1e78441 100644 --- a/cc/texture_layer_impl.cc +++ b/cc/texture_layer_impl.cc @@ -45,7 +45,12 @@ void TextureLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQu gfx::Rect opaqueRect(contentsOpaque() ? quadRect : gfx::Rect()); scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_externalTextureResource, m_premultipliedAlpha, m_uvRect, m_flipped); - quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); + + // Perform explicit clipping on a quad to avoid setting a scissor later. + if (sharedQuadState->is_clipped && quad->PerformClipping()) + sharedQuadState->is_clipped = false; + if (!quad->rect.IsEmpty()) + quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); } void TextureLayerImpl::didDraw(ResourceProvider* resourceProvider) |