Skip to content

Commit

Permalink
Cherry-pick 267599@main (499bdf9). https://bugs.webkit.org/show_bug.c…
Browse files Browse the repository at this point in the history
…gi?id=261022

    Move filter specific code from BitmapTextureGL to TextureMapperGL.
    https://bugs.webkit.org/show_bug.cgi?id=261022

    Reviewed by Fujii Hironori.

    This is a preparation refactoring for https://bugs.webkit.org/show_bug.cgi?id=231653.

    To fix the issue above, we have to change the number of passes needed to
    do blur filtering according to the standard deviation of the blur.
    Now the number of passes for each filter is specified in
    BitmapTextureGL.cpp but other parameters regarding filtering such as
    shader options are specified in TextureMapperGL.cpp, which leads to the
    inconsistency and low readability.

    This change moves filter specific code from BitmapTextureGL.cpp
    to TextureMapperGL.cpp

    * Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp:
    (WebCore::BitmapTextureGL::applyFilters):
    (WebCore::getPassesRequiredForFilter): Deleted.
    * Source/WebCore/platform/graphics/texmap/BitmapTextureGL.h:
    (WebCore::BitmapTextureGL::FilterInfo::FilterInfo):
    (WebCore::BitmapTextureGL::setFilterInfo):
    * Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp:
    (WebCore::TextureMapperGL::drawTexture):
    (WebCore::TextureMapperGL::drawTexturePlanarYUV):
    (WebCore::TextureMapperGL::drawTextureSemiPlanarYUV):
    (WebCore::TextureMapperGL::drawTexturePackedYUV):
    (WebCore::TextureMapperGL::drawFilterPass):
    (WebCore::getPassesRequiredForFilter):
    (WebCore::TextureMapperGL::applyFilter):
    (WebCore::TextureMapperGL::drawFiltered): Deleted.
    * Source/WebCore/platform/graphics/texmap/TextureMapperGL.h:
    * Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp:
    (WebCore::TextureMapperLayer::paintIntoSurface):

    Canonical link: https://commits.webkit.org/267599@main
  • Loading branch information
Akihiro Kiuchi authored and carlosgcampos committed Sep 8, 2023
1 parent 9b290c2 commit 2b0a1e3
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 57 deletions.
52 changes: 6 additions & 46 deletions Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,66 +162,26 @@ void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, co
updateContents(imageData, targetRect, offset, bytesPerLine);
}

static unsigned getPassesRequiredForFilter(FilterOperation::Type type)
{
switch (type) {
case FilterOperation::Type::Grayscale:
case FilterOperation::Type::Sepia:
case FilterOperation::Type::Saturate:
case FilterOperation::Type::HueRotate:
case FilterOperation::Type::Invert:
case FilterOperation::Type::Brightness:
case FilterOperation::Type::Contrast:
case FilterOperation::Type::Opacity:
return 1;
case FilterOperation::Type::Blur:
case FilterOperation::Type::DropShadow:
// We use two-passes (vertical+horizontal) for blur and drop-shadow.
return 2;
default:
return 0;
}
}

RefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper& textureMapper, const FilterOperations& filters, bool defersLastFilter)
RefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper& textureMapper, const FilterOperations& filters, bool defersLastFilterPass)
{
if (filters.isEmpty())
return this;

TextureMapperGL& texmapGL = static_cast<TextureMapperGL&>(textureMapper);
RefPtr<BitmapTexture> previousSurface = texmapGL.currentSurface();
RefPtr<BitmapTexture> resultSurface = this;
RefPtr<BitmapTexture> intermediateSurface;
RefPtr<BitmapTexture> spareSurface;

m_filterInfo = FilterInfo();
RefPtr<BitmapTexture> surface = this;

for (size_t i = 0; i < filters.size(); ++i) {
RefPtr<FilterOperation> filter = filters.operations()[i];
ASSERT(filter);

int numPasses = getPassesRequiredForFilter(filter->type());
for (int j = 0; j < numPasses; ++j) {
bool last = (i == filters.size() - 1) && (j == numPasses - 1);
if (defersLastFilter && last) {
toBitmapTextureGL(resultSurface.get())->m_filterInfo = BitmapTextureGL::FilterInfo(filter.copyRef(), j, spareSurface.copyRef());
break;
}

if (!intermediateSurface)
intermediateSurface = texmapGL.acquireTextureFromPool(contentSize(), BitmapTexture::SupportsAlpha);
texmapGL.bindSurface(intermediateSurface.get());
texmapGL.drawFiltered(*resultSurface.get(), spareSurface.get(), *filter, j);
if (!j && filter->type() == FilterOperation::Type::DropShadow) {
spareSurface = resultSurface;
resultSurface = nullptr;
}
std::swap(resultSurface, intermediateSurface);
}
bool lastFilter = (i == filters.size() - 1);

surface = texmapGL.applyFilter(surface, filter, defersLastFilterPass && lastFilter);
}

texmapGL.bindSurface(previousSurface.get());
return resultSurface;
return surface;
}

void BitmapTextureGL::initializeStencil()
Expand Down
9 changes: 6 additions & 3 deletions Source/WebCore/platform/graphics/texmap/BitmapTextureGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,22 @@ class BitmapTextureGL : public BitmapTexture {
void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine) override;
bool isBackedByOpenGL() const override { return true; }

RefPtr<BitmapTexture> applyFilters(TextureMapper&, const FilterOperations&, bool defersLastFilter) override;
RefPtr<BitmapTexture> applyFilters(TextureMapper&, const FilterOperations&, bool defersLastFilterPass) override;
struct FilterInfo {
RefPtr<FilterOperation> filter;
RefPtr<const FilterOperation> filter;
unsigned pass;
RefPtr<BitmapTexture> contentTexture;

FilterInfo(RefPtr<FilterOperation>&& f = nullptr, unsigned p = 0, RefPtr<BitmapTexture>&& t = nullptr)
FilterInfo(RefPtr<const FilterOperation>&& f = nullptr, unsigned p = 0, RefPtr<BitmapTexture>&& t = nullptr)
: filter(WTFMove(f))
, pass(p)
, contentTexture(WTFMove(t))
{ }
};

const FilterInfo* filterInfo() const { return &m_filterInfo; }
void setFilterInfo(FilterInfo&& filterInfo) { m_filterInfo = WTFMove(filterInfo); }

ClipStack& clipStack() { return m_clipStack; }

GLint internalFormat() const { return m_internalFormat; }
Expand Down
61 changes: 56 additions & 5 deletions Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ void TextureMapperGL::drawTexture(GLuint texture, Flags flags, const IntSize& te
if (wrapMode() == RepeatWrap && !m_contextAttributes.supportsNPOTTextures)
options.add(TextureMapperShaderProgram::ManualRepeat);

RefPtr<FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
RefPtr<const FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
GLuint filterContentTextureID = 0;

if (filter) {
Expand Down Expand Up @@ -530,7 +530,7 @@ void TextureMapperGL::drawTexturePlanarYUV(const std::array<GLuint, 3>& textures
if (wrapMode() == RepeatWrap && !m_contextAttributes.supportsNPOTTextures)
options.add(TextureMapperShaderProgram::ManualRepeat);

RefPtr<FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
RefPtr<const FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
GLuint filterContentTextureID = 0;

if (filter) {
Expand Down Expand Up @@ -590,7 +590,7 @@ void TextureMapperGL::drawTextureSemiPlanarYUV(const std::array<GLuint, 2>& text
if (wrapMode() == RepeatWrap && !m_contextAttributes.supportsNPOTTextures)
options.add(TextureMapperShaderProgram::ManualRepeat);

RefPtr<FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
RefPtr<const FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
GLuint filterContentTextureID = 0;

if (filter) {
Expand Down Expand Up @@ -642,7 +642,7 @@ void TextureMapperGL::drawTexturePackedYUV(GLuint texture, const std::array<GLfl
if (wrapMode() == RepeatWrap && !m_contextAttributes.supportsNPOTTextures)
options.add(TextureMapperShaderProgram::ManualRepeat);

RefPtr<FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
RefPtr<const FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: nullptr;
GLuint filterContentTextureID = 0;

if (filter) {
Expand Down Expand Up @@ -831,7 +831,7 @@ void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram& pr
drawTexturedQuadWithProgram(program, { { texture, program.samplerLocation() } }, flags, rect, modelViewMatrix, opacity);
}

void TextureMapperGL::drawFiltered(const BitmapTexture& sampler, const BitmapTexture* contentTexture, const FilterOperation& filter, int pass)
void TextureMapperGL::drawFilterPass(const BitmapTexture& sampler, const BitmapTexture* contentTexture, const FilterOperation& filter, int pass)
{
// For standard filters, we always draw the whole texture without transformations.
TextureMapperShaderProgram::Options options = optionsForFilterType(filter.type(), pass);
Expand All @@ -842,6 +842,57 @@ void TextureMapperGL::drawFiltered(const BitmapTexture& sampler, const BitmapTex
drawTexturedQuadWithProgram(program.get(), static_cast<const BitmapTextureGL&>(sampler).id(), 0, targetRect, TransformationMatrix(), 1);
}

static int getPassesRequiredForFilter(const FilterOperation& filter)
{
switch (filter.type()) {
case FilterOperation::Type::Grayscale:
case FilterOperation::Type::Sepia:
case FilterOperation::Type::Saturate:
case FilterOperation::Type::HueRotate:
case FilterOperation::Type::Invert:
case FilterOperation::Type::Brightness:
case FilterOperation::Type::Contrast:
case FilterOperation::Type::Opacity:
return 1;
case FilterOperation::Type::Blur:
case FilterOperation::Type::DropShadow:
// We use two-passes (vertical+horizontal) for blur and drop-shadow.
return 2;
default:
return 0;
}
}

RefPtr<BitmapTexture> TextureMapperGL::applyFilter(RefPtr<BitmapTexture> sourceTexture, const RefPtr<const FilterOperation>& filter, bool defersLastPass)
{
RefPtr<BitmapTexture> resultTexture = acquireTextureFromPool(sourceTexture->contentSize(), BitmapTexture::SupportsAlpha);
RefPtr<BitmapTexture> contentTexture;
int numPass = getPassesRequiredForFilter(*filter);

std::swap(resultTexture, sourceTexture);

for (int pass = 0; pass < numPass; pass++) {
if (defersLastPass && pass == numPass - 1) {
auto filterInfo = BitmapTextureGL::FilterInfo(filter.copyRef(), pass, contentTexture.copyRef());
toBitmapTextureGL(resultTexture.get())->setFilterInfo(WTFMove(filterInfo));
break;
}

std::swap(resultTexture, sourceTexture);

bindSurface(resultTexture.get());

drawFilterPass(*sourceTexture, contentTexture.get(), *filter, pass);

if (!pass && filter->type() == FilterOperation::Type::DropShadow) {
std::swap(contentTexture, sourceTexture);
sourceTexture = acquireTextureFromPool(contentTexture->contentSize(), BitmapTexture::SupportsAlpha);
}
}

return resultTexture;
}

static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool mirrored, double zNear, double zFar)
{
const double nearValue = std::min(zNear + 1, 9999999.0);
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/platform/graphics/texmap/TextureMapperGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ class TextureMapperGL : public TextureMapper {
Ref<BitmapTexture> createTexture() override;
void setDepthRange(double zNear, double zFar) override;

void drawFiltered(const BitmapTexture& sourceTexture, const BitmapTexture* contentTexture, const FilterOperation&, int pass);
RefPtr<BitmapTexture> applyFilter(RefPtr<BitmapTexture> sourceTexture, const RefPtr<const FilterOperation>&, bool defersLastPass);

void drawTextureExternalOES(GLuint texture, Flags, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity);

private:
void drawFilterPass(const BitmapTexture& sourceTexture, const BitmapTexture* contentTexture, const FilterOperation&, int pass);
void drawTexturedQuadWithProgram(TextureMapperShaderProgram&, uint32_t texture, Flags, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity);
void drawTexturedQuadWithProgram(TextureMapperShaderProgram&, const Vector<std::pair<GLuint, GLuint> >& texturesAndSamplers, Flags, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity);
void draw(const FloatRect&, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram&, GLenum drawingMode, Flags);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,8 @@ void TextureMapperLayer::paintIntoSurface(TextureMapperPaintOptions& options)

bool hasMask = !!m_state.maskLayer;
bool hasReplicaMask = options.replicaLayer == this && m_state.replicaLayer->m_state.maskLayer;
bool defersLastFilter = !hasMask && !hasReplicaMask;
options.surface = options.surface->applyFilters(options.textureMapper, m_currentFilters, defersLastFilter);
bool defersLastFilterPass = !hasMask && !hasReplicaMask;
options.surface = options.surface->applyFilters(options.textureMapper, m_currentFilters, defersLastFilterPass);
options.textureMapper.bindSurface(options.surface.get());
if (hasMask)
m_state.maskLayer->applyMask(options);
Expand Down

0 comments on commit 2b0a1e3

Please sign in to comment.