Skip to content
Permalink
Browse files
Align WebGL draw call functions
https://bugs.webkit.org/show_bug.cgi?id=241347

Patch by Alexey Knyazev <3479527+lexaknyazev@users.noreply.github.com> on 2022-06-13
Reviewed by Kimmo Kinnunen.

Some draw commands did not have implicit clears,
inspector helpers, and post-draw notifications.

* Source/WebCore/html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::drawRangeElements):
* Source/WebCore/html/canvas/WebGLMultiDraw.cpp:
(WebCore::WebGLMultiDraw::multiDrawArraysWEBGL):
(WebCore::WebGLMultiDraw::multiDrawArraysInstancedWEBGL):
(WebCore::WebGLMultiDraw::multiDrawElementsWEBGL):
(WebCore::WebGLMultiDraw::multiDrawElementsInstancedWEBGL):
* Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::InspectorScopedShaderProgramHighlight::InspectorScopedShaderProgramHighlight):
(WebCore::InspectorScopedShaderProgramHighlight::~InspectorScopedShaderProgramHighlight):
(WebCore::InspectorScopedShaderProgramHighlight::showHighlight):
(WebCore::InspectorScopedShaderProgramHighlight::hideHighlight):
(WebCore::InspectorScopedShaderProgramHighlight::saveBlendValue):
(WebCore::InspectorScopedShaderProgramHighlight::hasBufferBinding):
(WebCore::InspectorScopedShaderProgramHighlight::hasFramebufferParameterAttachment):
(WebCore::WebGLRenderingContextBase::drawArraysInstanced):
(WebCore::WebGLRenderingContextBase::drawElementsInstanced):
(WebCore::InspectorScopedShaderProgramHighlight::showHightlight): Deleted.
* Source/WebCore/html/canvas/WebGLRenderingContextBase.h:

Canonical link: https://commits.webkit.org/251491@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295486 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
lexaknyazev authored and webkit-commit-queue committed Jun 13, 2022
1 parent 079a232 commit cb33047e076bd189226dafb137d0e5eeabc614e0
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 106 deletions.
@@ -1608,7 +1608,19 @@ void WebGL2RenderingContext::drawRangeElements(GCGLenum mode, GCGLuint start, GC
return;
if (!validateVertexArrayObject("drawRangeElements"))
return;
m_context->drawRangeElements(mode, start, end, count, type, offset);

if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
return;

clearIfComposited(ClearCallerDrawOrClear);

{
InspectorScopedShaderProgramHighlight scopedHighlight(*this, m_currentProgram.get());

m_context->drawRangeElements(mode, start, end, count, type, offset);
}

markContextChangedAndNotifyCanvasObserver();
}

void WebGL2RenderingContext::drawBuffers(const Vector<GCGLenum>& buffers)
@@ -28,6 +28,8 @@
#if ENABLE(WEBGL)
#include "WebGLMultiDraw.h"

#include "InspectorInstrumentation.h"

#include <wtf/IsoMallocInlines.h>

namespace WebCore {
@@ -65,7 +67,21 @@ void WebGLMultiDraw::multiDrawArraysWEBGL(GCGLenum mode, Int32List firstsList, G
return;
}

m_context->graphicsContextGL()->multiDrawArraysANGLE(mode, GCGLSpanTuple { firstsList.data() + firstsOffset, countsList.data() + countsOffset, static_cast<size_t>(drawcount) });
if (!m_context->validateVertexArrayObject("multiDrawArraysWEBGL"))
return;

if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
return;

m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);

{
InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());

m_context->graphicsContextGL()->multiDrawArraysANGLE(mode, GCGLSpanTuple { firstsList.data() + firstsOffset, countsList.data() + countsOffset, static_cast<size_t>(drawcount) });
}

m_context->markContextChangedAndNotifyCanvasObserver();
}

void WebGLMultiDraw::multiDrawArraysInstancedWEBGL(GCGLenum mode, Int32List firstsList, GCGLuint firstsOffset, Int32List countsList, GCGLuint countsOffset, Int32List instanceCountsList, GCGLuint instanceCountsOffset, GCGLsizei drawcount)
@@ -80,7 +96,21 @@ void WebGLMultiDraw::multiDrawArraysInstancedWEBGL(GCGLenum mode, Int32List firs
return;
}

m_context->graphicsContextGL()->multiDrawArraysInstancedANGLE(mode, GCGLSpanTuple { firstsList.data() + firstsOffset, countsList.data() + countsOffset, instanceCountsList.data() + instanceCountsOffset, static_cast<size_t>(drawcount) });
if (!m_context->validateVertexArrayObject("multiDrawArraysInstancedWEBGL"))
return;

if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
return;

m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);

{
InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());

m_context->graphicsContextGL()->multiDrawArraysInstancedANGLE(mode, GCGLSpanTuple { firstsList.data() + firstsOffset, countsList.data() + countsOffset, instanceCountsList.data() + instanceCountsOffset, static_cast<size_t>(drawcount) });
}

m_context->markContextChangedAndNotifyCanvasObserver();
}

void WebGLMultiDraw::multiDrawElementsWEBGL(GCGLenum mode, Int32List countsList, GCGLuint countsOffset, GCGLenum type, Int32List offsetsList, GCGLuint offsetsOffset, GCGLsizei drawcount)
@@ -94,7 +124,21 @@ void WebGLMultiDraw::multiDrawElementsWEBGL(GCGLenum mode, Int32List countsList,
return;
}

m_context->graphicsContextGL()->multiDrawElementsANGLE(mode, GCGLSpanTuple { countsList.data() + countsOffset, offsetsList.data() + offsetsOffset, static_cast<size_t>(drawcount) }, type);
if (!m_context->validateVertexArrayObject("multiDrawElementsWEBGL"))
return;

if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
return;

m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);

{
InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());

m_context->graphicsContextGL()->multiDrawElementsANGLE(mode, GCGLSpanTuple { countsList.data() + countsOffset, offsetsList.data() + offsetsOffset, static_cast<size_t>(drawcount) }, type);
}

m_context->markContextChangedAndNotifyCanvasObserver();
}

void WebGLMultiDraw::multiDrawElementsInstancedWEBGL(GCGLenum mode, Int32List countsList, GCGLuint countsOffset, GCGLenum type, Int32List offsetsList, GCGLuint offsetsOffset, Int32List instanceCountsList, GCGLuint instanceCountsOffset, GCGLsizei drawcount)
@@ -109,7 +153,21 @@ void WebGLMultiDraw::multiDrawElementsInstancedWEBGL(GCGLenum mode, Int32List co
return;
}

m_context->graphicsContextGL()->multiDrawElementsInstancedANGLE(mode, GCGLSpanTuple { countsList.data() + countsOffset, offsetsList.data() + offsetsOffset, instanceCountsList.data() + instanceCountsOffset, static_cast<size_t>(drawcount) }, type);
if (!m_context->validateVertexArrayObject("multiDrawElementsInstancedWEBGL"))
return;

if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
return;

m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);

{
InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());

m_context->graphicsContextGL()->multiDrawElementsInstancedANGLE(mode, GCGLSpanTuple { countsList.data() + countsOffset, offsetsList.data() + offsetsOffset, instanceCountsList.data() + instanceCountsOffset, static_cast<size_t>(drawcount) }, type);
}

m_context->markContextChangedAndNotifyCanvasObserver();
}

bool WebGLMultiDraw::validateDrawcount(const char* functionName, GCGLsizei drawcount)
@@ -671,122 +671,103 @@ static bool possibleFormatAndTypeForInternalFormat(GCGLenum internalFormat, GCGL

#endif

class InspectorScopedShaderProgramHighlight {
public:
InspectorScopedShaderProgramHighlight(WebGLRenderingContextBase& context, WebGLProgram* program)
: m_context(context)
, m_program(program)
{
showHightlight();
}
InspectorScopedShaderProgramHighlight::InspectorScopedShaderProgramHighlight(WebGLRenderingContextBase& context, WebGLProgram* program)
: m_context(context)
, m_program(program)
{
showHighlight();
}

~InspectorScopedShaderProgramHighlight()
{
hideHighlight();
}
InspectorScopedShaderProgramHighlight::~InspectorScopedShaderProgramHighlight()
{
hideHighlight();
}

private:
void showHightlight()
{
if (!m_program || LIKELY(!InspectorInstrumentation::isWebGLProgramHighlighted(m_context, *m_program)))
return;
void InspectorScopedShaderProgramHighlight::showHighlight()
{
if (!m_program || LIKELY(!InspectorInstrumentation::isWebGLProgramHighlighted(m_context, *m_program)))
return;

if (hasBufferBinding(GraphicsContextGL::FRAMEBUFFER_BINDING)) {
if (!hasBufferBinding(GraphicsContextGL::RENDERBUFFER_BINDING))
return;
if (hasFramebufferParameterAttachment(GraphicsContextGL::DEPTH_ATTACHMENT))
return;
if (hasFramebufferParameterAttachment(GraphicsContextGL::STENCIL_ATTACHMENT))
return;
if (hasBufferBinding(GraphicsContextGL::FRAMEBUFFER_BINDING)) {
if (!hasBufferBinding(GraphicsContextGL::RENDERBUFFER_BINDING))
return;
if (hasFramebufferParameterAttachment(GraphicsContextGL::DEPTH_ATTACHMENT))
return;
if (hasFramebufferParameterAttachment(GraphicsContextGL::STENCIL_ATTACHMENT))
return;
#if ENABLE(WEBGL2)
if (hasFramebufferParameterAttachment(GraphicsContextGL::DEPTH_STENCIL_ATTACHMENT))
return;
if (hasFramebufferParameterAttachment(GraphicsContextGL::DEPTH_STENCIL_ATTACHMENT))
return;
#endif
}

saveBlendValue(GraphicsContextGL::BLEND_COLOR, m_savedBlend.color);
saveBlendValue(GraphicsContextGL::BLEND_EQUATION_RGB, m_savedBlend.equationRGB);
saveBlendValue(GraphicsContextGL::BLEND_EQUATION_ALPHA, m_savedBlend.equationAlpha);
saveBlendValue(GraphicsContextGL::BLEND_SRC_RGB, m_savedBlend.srcRGB);
saveBlendValue(GraphicsContextGL::BLEND_SRC_ALPHA, m_savedBlend.srcAlpha);
saveBlendValue(GraphicsContextGL::BLEND_DST_RGB, m_savedBlend.dstRGB);
saveBlendValue(GraphicsContextGL::BLEND_DST_ALPHA, m_savedBlend.dstAlpha);
saveBlendValue(GraphicsContextGL::BLEND, m_savedBlend.enabled);
}

static const GCGLfloat red = 111.0 / 255.0;
static const GCGLfloat green = 168.0 / 255.0;
static const GCGLfloat blue = 220.0 / 255.0;
static const GCGLfloat alpha = 2.0 / 3.0;
saveBlendValue(GraphicsContextGL::BLEND_COLOR, m_savedBlend.color);
saveBlendValue(GraphicsContextGL::BLEND_EQUATION_RGB, m_savedBlend.equationRGB);
saveBlendValue(GraphicsContextGL::BLEND_EQUATION_ALPHA, m_savedBlend.equationAlpha);
saveBlendValue(GraphicsContextGL::BLEND_SRC_RGB, m_savedBlend.srcRGB);
saveBlendValue(GraphicsContextGL::BLEND_SRC_ALPHA, m_savedBlend.srcAlpha);
saveBlendValue(GraphicsContextGL::BLEND_DST_RGB, m_savedBlend.dstRGB);
saveBlendValue(GraphicsContextGL::BLEND_DST_ALPHA, m_savedBlend.dstAlpha);
saveBlendValue(GraphicsContextGL::BLEND, m_savedBlend.enabled);

m_context.enable(GraphicsContextGL::BLEND);
m_context.blendColor(red, green, blue, alpha);
m_context.blendEquation(GraphicsContextGL::FUNC_ADD);
m_context.blendFunc(GraphicsContextGL::CONSTANT_COLOR, GraphicsContextGL::ONE_MINUS_SRC_ALPHA);
static const GCGLfloat red = 111.0 / 255.0;
static const GCGLfloat green = 168.0 / 255.0;
static const GCGLfloat blue = 220.0 / 255.0;
static const GCGLfloat alpha = 2.0 / 3.0;

m_didApply = true;
}
m_context.enable(GraphicsContextGL::BLEND);
m_context.blendColor(red, green, blue, alpha);
m_context.blendEquation(GraphicsContextGL::FUNC_ADD);
m_context.blendFunc(GraphicsContextGL::CONSTANT_COLOR, GraphicsContextGL::ONE_MINUS_SRC_ALPHA);

void hideHighlight()
{
if (!m_didApply)
return;
m_didApply = true;
}

if (!m_savedBlend.enabled)
m_context.disable(GraphicsContextGL::BLEND);
void InspectorScopedShaderProgramHighlight::hideHighlight()
{
if (!m_didApply)
return;

const RefPtr<Float32Array>& color = m_savedBlend.color;
m_context.blendColor(color->item(0), color->item(1), color->item(2), color->item(3));
m_context.blendEquationSeparate(m_savedBlend.equationRGB, m_savedBlend.equationAlpha);
m_context.blendFuncSeparate(m_savedBlend.srcRGB, m_savedBlend.dstRGB, m_savedBlend.srcAlpha, m_savedBlend.dstAlpha);
if (!m_savedBlend.enabled)
m_context.disable(GraphicsContextGL::BLEND);

m_savedBlend.color = nullptr;
const RefPtr<Float32Array>& color = m_savedBlend.color;
m_context.blendColor(color->item(0), color->item(1), color->item(2), color->item(3));
m_context.blendEquationSeparate(m_savedBlend.equationRGB, m_savedBlend.equationAlpha);
m_context.blendFuncSeparate(m_savedBlend.srcRGB, m_savedBlend.dstRGB, m_savedBlend.srcAlpha, m_savedBlend.dstAlpha);

m_didApply = false;
}
m_savedBlend.color = nullptr;

template <typename T>
void saveBlendValue(GCGLenum attachment, T& destination)
{
WebGLAny param = m_context.getParameter(attachment);
if (std::holds_alternative<T>(param))
destination = std::get<T>(param);
}
m_didApply = false;
}

bool hasBufferBinding(GCGLenum pname)
{
WebGLAny binding = m_context.getParameter(pname);
if (pname == GraphicsContextGL::FRAMEBUFFER_BINDING)
return std::holds_alternative<RefPtr<WebGLFramebuffer>>(binding) && std::get<RefPtr<WebGLFramebuffer>>(binding);
if (pname == GraphicsContextGL::RENDERBUFFER_BINDING)
return std::holds_alternative<RefPtr<WebGLRenderbuffer>>(binding) && std::get<RefPtr<WebGLRenderbuffer>>(binding);
return false;
}
template <typename T>
void InspectorScopedShaderProgramHighlight::saveBlendValue(GCGLenum attachment, T& destination)
{
WebGLAny param = m_context.getParameter(attachment);
if (std::holds_alternative<T>(param))
destination = std::get<T>(param);
}

bool hasFramebufferParameterAttachment(GCGLenum attachment)
{
WebGLAny attachmentParameter = m_context.getFramebufferAttachmentParameter(GraphicsContextGL::FRAMEBUFFER, attachment, GraphicsContextGL::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
if (!std::holds_alternative<unsigned>(attachmentParameter))
return false;
if (std::get<unsigned>(attachmentParameter) != static_cast<unsigned>(GraphicsContextGL::RENDERBUFFER))
return false;
return true;
}
bool InspectorScopedShaderProgramHighlight::hasBufferBinding(GCGLenum pname)
{
WebGLAny binding = m_context.getParameter(pname);
if (pname == GraphicsContextGL::FRAMEBUFFER_BINDING)
return std::holds_alternative<RefPtr<WebGLFramebuffer>>(binding) && std::get<RefPtr<WebGLFramebuffer>>(binding);
if (pname == GraphicsContextGL::RENDERBUFFER_BINDING)
return std::holds_alternative<RefPtr<WebGLRenderbuffer>>(binding) && std::get<RefPtr<WebGLRenderbuffer>>(binding);
return false;
}

struct {
RefPtr<Float32Array> color;
unsigned equationRGB { 0 };
unsigned equationAlpha { 0 };
unsigned srcRGB { 0 };
unsigned srcAlpha { 0 };
unsigned dstRGB { 0 };
unsigned dstAlpha { 0 };
bool enabled { false };
} m_savedBlend;

WebGLRenderingContextBase& m_context;
WebGLProgram* m_program { nullptr };
bool m_didApply { false };
};
bool InspectorScopedShaderProgramHighlight::hasFramebufferParameterAttachment(GCGLenum attachment)
{
WebGLAny attachmentParameter = m_context.getFramebufferAttachmentParameter(GraphicsContextGL::FRAMEBUFFER, attachment, GraphicsContextGL::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
if (!std::holds_alternative<unsigned>(attachmentParameter))
return false;
if (std::get<unsigned>(attachmentParameter) != static_cast<unsigned>(GraphicsContextGL::RENDERBUFFER))
return false;
return true;
}

static bool isHighPerformanceContext(const RefPtr<GraphicsContextGL>& context)
{
@@ -8010,6 +7991,9 @@ void WebGLRenderingContextBase::drawArraysInstanced(GCGLenum mode, GCGLint first
if (!validateVertexArrayObject("drawArraysInstanced"))
return;

if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
return;

clearIfComposited(ClearCallerDrawOrClear);

#if !USE(ANGLE)
@@ -8027,7 +8011,11 @@ void WebGLRenderingContextBase::drawArraysInstanced(GCGLenum mode, GCGLint first
checkTextureCompleteness("drawArraysInstanced", true);
#endif

m_context->drawArraysInstanced(mode, first, count, primcount);
{
InspectorScopedShaderProgramHighlight scopedHighlight(*this, m_currentProgram.get());

m_context->drawArraysInstanced(mode, first, count, primcount);
}

#if !USE(ANGLE)
if (!isGLES2Compliant() && vertexAttrib0Simulated)
@@ -8051,6 +8039,9 @@ void WebGLRenderingContextBase::drawElementsInstanced(GCGLenum mode, GCGLsizei c
if (!validateVertexArrayObject("drawElementsInstanced"))
return;

if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
return;

clearIfComposited(ClearCallerDrawOrClear);

#if !USE(ANGLE)
@@ -8070,7 +8061,11 @@ void WebGLRenderingContextBase::drawElementsInstanced(GCGLenum mode, GCGLsizei c
checkTextureCompleteness("drawElementsInstanced", true);
#endif

m_context->drawElementsInstanced(mode, count, type, static_cast<GCGLintptr>(offset), primcount);
{
InspectorScopedShaderProgramHighlight scopedHighlight(*this, m_currentProgram.get());

m_context->drawElementsInstanced(mode, count, type, static_cast<GCGLintptr>(offset), primcount);
}

#if !USE(ANGLE)
if (!isGLES2Compliant() && vertexAttrib0Simulated)

0 comments on commit cb33047

Please sign in to comment.