Skip to content

Commit

Permalink
TextureMapper: Calculate zFar and zNear for the projection matrix
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=244564

Reviewed by Darin Adler.

TextureMapper was using fixed zFar and zNear values, (-99999,
9999999). These were too big for 16 bits depth buffer on Linux.
<https://bugs.webkit.org/show_bug.cgi?id=244526#c2>

Changed TextureMapperLayer::computeTransformsRecursive to calculate
zFar and zNear.

* LayoutTests/platform/glib/TestExpectations:
Unmarked imported/w3c/web-platform-tests/css/css-transforms/perspective-split-by-zero-w.html
* Source/WebCore/platform/graphics/texmap/TextureMapper.h:
(WebCore::TextureMapper::setDepthRange):
* Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp:
(WebCore::createProjectionMatrix):
(WebCore::TextureMapperGL::bindDefaultSurface):
(WebCore::TextureMapperGL::bindSurface):
(WebCore::TextureMapperGL::setDepthRange):
* Source/WebCore/platform/graphics/texmap/TextureMapperGL.h:
* Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp:
(WebCore::TextureMapperComputeTransformData::updateDepthRange):
(WebCore::TextureMapperLayer::computeTransformsRecursive):
(WebCore::TextureMapperLayer::paint):
* Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h:

Canonical link: https://commits.webkit.org/254897@main
  • Loading branch information
fujii committed Sep 27, 2022
1 parent 7605a55 commit 922f8f0
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 18 deletions.
1 change: 1 addition & 0 deletions Source/WebCore/platform/graphics/texmap/TextureMapper.h
Expand Up @@ -83,6 +83,7 @@ class TextureMapper {
virtual void endPreserves3D() { };
virtual Ref<BitmapTexture> createTexture() = 0;
virtual Ref<BitmapTexture> createTexture(int internalFormat) = 0;
virtual void setDepthRange(double zNear, double zFar) = 0;

virtual void beginPainting(PaintFlags = 0) { }
virtual void endPainting() { }
Expand Down
27 changes: 17 additions & 10 deletions Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
Expand Up @@ -72,6 +72,8 @@ class TextureMapperGLData {
GLint previousDepthState { 0 };
GLint viewport[4] { 0, };
GLint previousScissor[4] { 0, };
double zNear { 0 };
double zFar { 0 };
RefPtr<BitmapTexture> currentSurface;
const BitmapTextureGL::FilterInfo* filterInfo { nullptr };

Expand Down Expand Up @@ -867,15 +869,14 @@ void TextureMapperGL::drawFiltered(const BitmapTexture& sampler, const BitmapTex
drawTexturedQuadWithProgram(program.get(), static_cast<const BitmapTextureGL&>(sampler).id(), 0, targetRect, TransformationMatrix(), 1);
}

static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool mirrored)
static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool mirrored, double zNear, double zFar)
{
const float nearValue = -99999;
const float farValue = 9999999;

return TransformationMatrix(2.0 / float(size.width()), 0, 0, 0,
0, (mirrored ? 2.0 : -2.0) / float(size.height()), 0, 0,
0, 0, -2.f / (farValue - nearValue), 0,
-1, mirrored ? -1 : 1, -(farValue + nearValue) / (farValue - nearValue), 1);
const double nearValue = std::min(zNear + 1, 9999999.0);
const double farValue = std::max(zFar - 1, -99999.0);
return TransformationMatrix(2.0 / size.width(), 0, 0, 0,
0, (mirrored ? 2.0 : -2.0) / size.height(), 0, 0,
0, 0, 2.0 / (farValue - nearValue), 0,
-1, mirrored ? -1 : 1, -(farValue + nearValue) / (farValue - nearValue), 1);
}

TextureMapperGL::~TextureMapperGL()
Expand All @@ -887,7 +888,7 @@ void TextureMapperGL::bindDefaultSurface()
{
glBindFramebuffer(GL_FRAMEBUFFER, data().targetFrameBuffer);
auto& viewport = data().viewport;
data().projectionMatrix = createProjectionMatrix(IntSize(viewport[2], viewport[3]), data().PaintFlags & PaintingMirrored);
data().projectionMatrix = createProjectionMatrix(IntSize(viewport[2], viewport[3]), data().PaintFlags & PaintingMirrored, data().zNear, data().zFar);
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
m_clipStack.apply();
data().currentSurface = nullptr;
Expand All @@ -901,7 +902,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surface)
}

static_cast<BitmapTextureGL*>(surface)->bindAsSurface();
data().projectionMatrix = createProjectionMatrix(surface->size(), true /* mirrored */);
data().projectionMatrix = createProjectionMatrix(surface->size(), true /* mirrored */, data().zNear, data().zFar);
data().currentSurface = surface;
}

Expand Down Expand Up @@ -1041,6 +1042,12 @@ Ref<BitmapTexture> TextureMapperGL::createTexture(GLint internalFormat)
return BitmapTextureGL::create(m_contextAttributes, internalFormat);
}

void TextureMapperGL::setDepthRange(double zNear, double zFar)
{
data().zNear = zNear;
data().zFar = zFar;
}

std::unique_ptr<TextureMapper> TextureMapper::platformCreateAccelerated()
{
return makeUnique<TextureMapperGL>();
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/platform/graphics/texmap/TextureMapperGL.h
Expand Up @@ -85,6 +85,7 @@ class TextureMapperGL : public TextureMapper {
IntSize maxTextureSize() const override { return IntSize(2000, 2000); }
Ref<BitmapTexture> createTexture() override { return createTexture(GL_DONT_CARE); }
Ref<BitmapTexture> createTexture(GLint internalFormat) override;
void setDepthRange(double zNear, double zFar) override;

void drawFiltered(const BitmapTexture& sourceTexture, const BitmapTexture* contentTexture, const FilterOperation&, int pass);

Expand Down
48 changes: 41 additions & 7 deletions Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
Expand Up @@ -44,6 +44,19 @@ class TextureMapperPaintOptions {
bool preserves3D { false };
};

struct TextureMapperLayer::ComputeTransformData {
double zNear { 0 };
double zFar { 0 };

void updateDepthRange(double z)
{
if (zNear < z)
zNear = z;
else if (zFar > z)
zFar = z;
}
};

TextureMapperLayer::TextureMapperLayer() = default;

TextureMapperLayer::~TextureMapperLayer()
Expand All @@ -54,7 +67,7 @@ TextureMapperLayer::~TextureMapperLayer()
removeFromParent();
}

void TextureMapperLayer::computeTransformsRecursive()
void TextureMapperLayer::computeTransformsRecursive(ComputeTransformData& data)
{
if (m_state.size.isEmpty() && m_state.masksToBounds)
return;
Expand Down Expand Up @@ -111,18 +124,37 @@ void TextureMapperLayer::computeTransformsRecursive()

m_state.visible = m_state.backfaceVisibility || !m_layerTransforms.combined.isBackFaceVisible();

auto calculateZ = [&](double x, double y) -> double {
double z = 0;
double w = 1;
m_layerTransforms.combined.map4ComponentPoint(x, y, z, w);
if (w <= 0) {
if (!z)
return 0;
if (z < 0)
return -std::numeric_limits<double>::infinity();
return std::numeric_limits<double>::infinity();
}
return z / w;
};

data.updateDepthRange(calculateZ(0, 0));
data.updateDepthRange(calculateZ(m_state.size.width(), 0));
data.updateDepthRange(calculateZ(0, m_state.size.height()));
data.updateDepthRange(calculateZ(m_state.size.width(), m_state.size.height()));

if (m_parent && m_parent->m_state.preserves3D)
m_centerZ = m_layerTransforms.combined.mapPoint(FloatPoint3D(m_state.size.width() / 2, m_state.size.height() / 2, 0)).z();
m_centerZ = calculateZ(m_state.size.width() / 2, m_state.size.height() / 2);

if (m_state.maskLayer)
m_state.maskLayer->computeTransformsRecursive();
m_state.maskLayer->computeTransformsRecursive(data);
if (m_state.replicaLayer)
m_state.replicaLayer->computeTransformsRecursive();
m_state.replicaLayer->computeTransformsRecursive(data);
if (m_state.backdropLayer)
m_state.backdropLayer->computeTransformsRecursive();
m_state.backdropLayer->computeTransformsRecursive(data);
for (auto* child : m_children) {
ASSERT(child->m_parent == this);
child->computeTransformsRecursive();
child->computeTransformsRecursive(data);
}

// Reorder children if needed on the way back up.
Expand All @@ -137,7 +169,9 @@ void TextureMapperLayer::computeTransformsRecursive()

void TextureMapperLayer::paint(TextureMapper& textureMapper)
{
computeTransformsRecursive();
ComputeTransformData data;
computeTransformsRecursive(data);
textureMapper.setDepthRange(data.zNear, data.zFar);

TextureMapperPaintOptions options(textureMapper);
options.textureMapper.bindSurface(0);
Expand Down
4 changes: 3 additions & 1 deletion Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
Expand Up @@ -111,7 +111,9 @@ class WEBCORE_EXPORT TextureMapperLayer : public CanMakeWeakPtr<TextureMapperLay
return m_parent->rootLayer();
return const_cast<TextureMapperLayer&>(*this);
}
void computeTransformsRecursive();

struct ComputeTransformData;
void computeTransformsRecursive(ComputeTransformData&);

static void sortByZOrder(Vector<TextureMapperLayer* >& array);

Expand Down

0 comments on commit 922f8f0

Please sign in to comment.