https://bugs.webkit.org/show_bug.cgi?id=77575
Reviewed by Martin Robinson.
Source/WebCore:
Maintain a clipping stack, that helps us use stencils in conjunction with scissors.
We apply scissors when the clip region is rectalinear, and stencil when it's not.
No behavior changes so no new tests.
* platform/graphics/opengl/TextureMapperGL.cpp:
(SharedGLData):
(WebCore::TextureMapperGLData::SharedGLData::SharedGLData):
(WebCore::TextureMapperGL::drawTexture):
(WebCore::TextureMapperGL::bindSurface):
(WebCore):
(WebCore::scissorClip):
(WebCore::TextureMapperGL::beginScissorClip):
(WebCore::TextureMapperGL::endScissorClip):
(WebCore::TextureMapperGL::beginClip):
(WebCore::TextureMapperGL::endClip):
* platform/graphics/opengl/TextureMapperGL.h:
(TextureMapperGL):
Source/WebKit2:
Instead of applying the scissor clip in QQuickWebPage, we trickle it down to
TextureMapperGL, and apply it there as part of beginClip(). All direct GL operations are
now cleaned out of QQuickWebPage.
* UIProcess/API/qt/qquickwebpage.cpp:
(QQuickWebPagePrivate::paintToCurrentGLContext):
* UIProcess/DrawingAreaProxy.h:
(WebKit::DrawingAreaProxy::paintToCurrentGLContext):
* UIProcess/DrawingAreaProxyImpl.cpp:
(WebKit::DrawingAreaProxyImpl::paintToCurrentGLContext):
* UIProcess/DrawingAreaProxyImpl.h:
(DrawingAreaProxyImpl):
* UIProcess/LayerTreeHostProxy.h:
(LayerTreeHostProxy):
* UIProcess/qt/LayerTreeHostProxyQt.cpp:
(WebKit::LayerTreeHostProxy::paintToCurrentGLContext):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106524
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-02-01 No'am Rosenthal <noam.rosenthal@nokia.com>
+
+ [Texmap] Use glScissors for clipping in TextureMapperGL when possible
+ https://bugs.webkit.org/show_bug.cgi?id=77575
+
+ Reviewed by Martin Robinson.
+
+ Maintain a clipping stack, that helps us use stencils in conjunction with scissors.
+ We apply scissors when the clip region is rectalinear, and stencil when it's not.
+
+ No behavior changes so no new tests.
+
+ * platform/graphics/opengl/TextureMapperGL.cpp:
+ (SharedGLData):
+ (WebCore::TextureMapperGLData::SharedGLData::SharedGLData):
+ (WebCore::TextureMapperGL::drawTexture):
+ (WebCore::TextureMapperGL::bindSurface):
+ (WebCore):
+ (WebCore::scissorClip):
+ (WebCore::TextureMapperGL::beginScissorClip):
+ (WebCore::TextureMapperGL::endScissorClip):
+ (WebCore::TextureMapperGL::beginClip):
+ (WebCore::TextureMapperGL::endClip):
+ * platform/graphics/opengl/TextureMapperGL.h:
+ (TextureMapperGL):
+
2012-02-01 Anders Carlsson <andersca@apple.com>
Move the scrolling coordinator to page/scrolling
ProgramInfo programs[ProgramCount];
int stencilIndex;
+ Vector<IntRect> clipStack;
- SharedGLData(GLContext glContext) : stencilIndex(1)
+ SharedGLData(GLContext glContext)
+ : stencilIndex(1)
{
glContextDataMap().add(glContext, this);
initializeShaders();
TextureMapperGLData()
: currentProgram(SharedGLData::NoProgram)
+ , previousProgram(0)
+ , previousScissorState(0)
, m_sharedGLData(TextureMapperGLData::SharedGLData::currentSharedGLData())
{ }
TransformationMatrix projectionMatrix;
int currentProgram;
- int previousProgram;
+ GLint previousProgram;
+ GLint previousScissorState;
RefPtr<SharedGLData> m_sharedGLData;
};
void TextureMapperGL::beginPainting()
{
-#if PLATFORM(QT)
+ // Make sure that no GL error code stays from previous operations.
+ glGetError();
+
if (!initializeOpenGLShims())
return;
- glGetIntegerv(GL_CURRENT_PROGRAM, &m_data->previousProgram);
+ glGetIntegerv(GL_CURRENT_PROGRAM, &data().previousProgram);
+ data().previousScissorState = glIsEnabled(GL_SCISSOR_TEST);
+
+ glEnable(GL_SCISSOR_TEST);
+#if PLATFORM(QT)
if (m_context) {
QPainter* painter = m_context->platformContext();
painter->save();
painter->beginNativePainting();
}
+#endif
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
bindSurface(0);
-#endif
}
void TextureMapperGL::endPainting()
{
-#if PLATFORM(QT)
glClearStencil(1);
glClear(GL_STENCIL_BUFFER_BIT);
- glUseProgram(m_data->previousProgram);
+ glUseProgram(data().previousProgram);
+
+ if (data().previousScissorState)
+ glEnable(GL_SCISSOR_TEST);
+ else
+ glDisable(GL_SCISSOR_TEST);
+
+#if PLATFORM(QT)
if (!m_context)
return;
QPainter* painter = m_context->platformContext();
}
GL_CMD(glDisable(GL_DEPTH_TEST))
+
GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4))
GL_CMD(glDisableVertexAttribArray(programInfo.vertexAttrib))
}
glStencilFunc(stencilIndex > 1 ? GL_GEQUAL : GL_ALWAYS, stencilIndex - 1, stencilIndex - 1);
GL_CMD(glViewport(0, 0, size().width(), size().height()))
m_textureMapper->data().projectionMatrix = createProjectionMatrix(size(), false);
- glDisable(GL_SCISSOR_TEST);
}
void BitmapTextureGL::destroy()
GL_CMD(glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1))
GL_CMD(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP))
GL_CMD(glViewport(0, 0, viewportSize().width(), viewportSize().height()))
+ data().sharedGLData().clipStack.append(IntRect(IntPoint::zero(), viewportSize()));
return;
}
surface->bind();
}
+static void scissorClip(const IntRect& rect)
+{
+ GLint viewport[4];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glScissor(rect.x(), viewport[3] - rect.maxY(), rect.width(), rect.height());
+}
+
+bool TextureMapperGL::beginScissorClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect)
+{
+ FloatQuad quad = modelViewMatrix.projectQuad(targetRect);
+ IntRect rect = quad.enclosingBoundingBox();
+
+ // Only use scissors on rectilinear clips.
+ if (!quad.isRectilinear() || rect.isEmpty()) {
+ data().sharedGLData().clipStack.append(IntRect());
+ return false;
+ }
+
+ // Intersect with previous clip.
+ if (!data().sharedGLData().clipStack.isEmpty())
+ rect.intersect(data().sharedGLData().clipStack.last());
+
+ scissorClip(rect);
+ data().sharedGLData().clipStack.append(rect);
+
+ return true;
+}
+
+bool TextureMapperGL::endScissorClip()
+{
+ data().sharedGLData().clipStack.removeLast();
+ ASSERT(!data().sharedGLData().clipStack.isEmpty());
+
+ IntRect rect = data().sharedGLData().clipStack.last();
+ if (rect.isEmpty())
+ return false;
+
+ scissorClip(rect);
+ return true;
+}
+
void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect)
{
+ if (beginScissorClip(modelViewMatrix, targetRect))
+ return;
TextureMapperGLData::SharedGLData::ShaderProgramIndex program = TextureMapperGLData::SharedGLData::ClipProgram;
const TextureMapperGLData::SharedGLData::ProgramInfo& programInfo = data().sharedGLData().programs[program];
GL_CMD(glUseProgram(programInfo.id))
void TextureMapperGL::endClip()
{
+ if (endScissorClip())
+ return;
+
data().sharedGLData().stencilIndex >>= 1;
- glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1);
+ glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1);
+
+ // After we've cleared the last non-rectalinear clip, we disable the stencil test.
+ if (data().sharedGLData().stencilIndex == 1)
+ GL_CMD(glDisable(GL_STENCIL_TEST))
+
}
PassRefPtr<BitmapTexture> TextureMapperGL::createTexture()
virtual bool isOpenGLBacked() const { return true; }
private:
+ bool beginScissorClip(const TransformationMatrix&, const FloatRect&);
+ bool endScissorClip();
inline TextureMapperGLData& data() { return *m_data; }
TextureMapperGLData* m_data;
GraphicsContext* m_context;
+2012-02-01 No'am Rosenthal <noam.rosenthal@nokia.com>
+
+ [Texmap] Use glScissors for clipping in TextureMapperGL when possible
+ https://bugs.webkit.org/show_bug.cgi?id=77575
+
+ Reviewed by Martin Robinson.
+
+ Instead of applying the scissor clip in QQuickWebPage, we trickle it down to
+ TextureMapperGL, and apply it there as part of beginClip(). All direct GL operations are
+ now cleaned out of QQuickWebPage.
+
+ * UIProcess/API/qt/qquickwebpage.cpp:
+ (QQuickWebPagePrivate::paintToCurrentGLContext):
+ * UIProcess/DrawingAreaProxy.h:
+ (WebKit::DrawingAreaProxy::paintToCurrentGLContext):
+ * UIProcess/DrawingAreaProxyImpl.cpp:
+ (WebKit::DrawingAreaProxyImpl::paintToCurrentGLContext):
+ * UIProcess/DrawingAreaProxyImpl.h:
+ (DrawingAreaProxyImpl):
+ * UIProcess/LayerTreeHostProxy.h:
+ (LayerTreeHostProxy):
+ * UIProcess/qt/LayerTreeHostProxyQt.cpp:
+ (WebKit::LayerTreeHostProxy::paintToCurrentGLContext):
+
2012-02-01 Dan Bernstein <mitz@apple.com>
WebKit2 part of <rdar://problem/10442663> Paginated display does not respect page-break-{before,after}
if (!drawingArea)
return;
- // Make sure that no GL error code stays from previous QT operations.
- glGetError();
-
- glEnable(GL_SCISSOR_TEST);
- ASSERT(!glGetError());
- const int left = clipRect.left();
- const int width = clipRect.width();
- const int bottom = q->canvas()->height() - (clipRect.bottom() + 1);
- const int height = clipRect.height();
-
- glScissor(left, bottom, width, height);
- ASSERT(!glGetError());
-
- drawingArea->paintToCurrentGLContext(transform, opacity);
-
- glDisable(GL_SCISSOR_TEST);
- ASSERT(!glGetError());
+ drawingArea->paintToCurrentGLContext(transform, opacity, clipRect);
}
struct PageProxyMaterial;
virtual WebCore::IntRect viewportVisibleRect() const { return contentsRect(); }
virtual WebCore::IntRect contentsRect() const;
virtual bool isBackingStoreReady() const { return true; }
- virtual void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float opacity) { }
+ virtual void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&) { }
virtual void paintLayerTree(BackingStore::PlatformGraphicsContext) { }
LayerTreeHostProxy* layerTreeHostProxy() const { return m_layerTreeHostProxy.get(); }
m_layerTreeHostProxy->paintToGraphicsContext(context);
}
-void DrawingAreaProxyImpl::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity)
+void DrawingAreaProxyImpl::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect)
{
if (m_layerTreeHostProxy)
- m_layerTreeHostProxy->paintToCurrentGLContext(matrix, opacity);
+ m_layerTreeHostProxy->paintToCurrentGLContext(matrix, opacity, clipRect);
}
#endif
#if USE(TILED_BACKING_STORE)
virtual void setVisibleContentsRectAndScale(const WebCore::IntRect& visibleContentsRect, float scale);
virtual void setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint&);
- virtual void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float opacity);
+ virtual void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float opacity, const WebCore::FloatRect&);
virtual void paintLayerTree(BackingStore::PlatformGraphicsContext);
void didReceiveLayerTreeHostProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
#endif
void deleteCompositingLayer(WebLayerID);
void setRootCompositingLayer(WebLayerID);
void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
- void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float);
+ void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&);
void paintToGraphicsContext(BackingStore::PlatformGraphicsContext);
void purgeGLResources();
void setVisibleContentsRectAndScale(const WebCore::IntRect&, float);
}
// This function needs to be reentrant.
-void LayerTreeHostProxy::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity)
+void LayerTreeHostProxy::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect)
{
if (!m_textureMapper)
m_textureMapper = TextureMapperGL::create();
node->setTextureMapper(m_textureMapper.get());
m_textureMapper->beginPainting();
m_textureMapper->bindSurface(0);
+ m_textureMapper->beginClip(TransformationMatrix(), clipRect);
if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
currentRootLayer->setOpacity(opacity);
}
node->paint();
+ m_textureMapper->endClip();
m_textureMapper->endPainting();
if (node->descendantsOrSelfHaveRunningAnimations()) {