Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8242354: support for bufImgOps (RescaleOp, LookupOp, ConvolveOp)
Co-authored-by: Artem Bochkarev <abochkarev@openjdk.org>
  • Loading branch information
Alexey Ushakov and Artem Bochkarev committed Jun 2, 2020
1 parent 0c519db commit a403550cebfb69e8cc8a947e2c71bdc55d6846e1
@@ -134,7 +134,7 @@ public static class MTLContextCaps extends ContextCapabilities {
* enabled and the hardware meets our minimum requirements.
*/
@Native
static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2);
public static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2);
/**
* This cap will only be set if the gradshader system property has been
* enabled and the hardware meets our minimum requirements.
@@ -52,6 +52,8 @@
import static sun.java2d.pipe.hw.AccelSurface.RT_TEXTURE;
import static sun.java2d.pipe.hw.ContextCapabilities.*;

import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_BIOP_SHADER;

public final class MTLGraphicsConfig extends CGraphicsConfig
implements AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig
{
@@ -157,7 +159,7 @@ public static MTLGraphicsConfig getConfig(CGraphicsDevice device,
ContextCapabilities caps = new MTLContext.MTLContextCaps(
CAPS_PS30 | CAPS_PS20 | CAPS_RT_PLAIN_ALPHA |
CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE |
CAPS_MULTITEXTURE | CAPS_TEXNONPOW2 | CAPS_TEXNONSQUARE,
CAPS_MULTITEXTURE | CAPS_TEXNONPOW2 | CAPS_TEXNONSQUARE | CAPS_EXT_BIOP_SHADER,
ids[0]);
return new MTLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
}
@@ -81,6 +81,31 @@ struct TxtFrameUniforms {
float extraAlpha;
};

struct TxtFrameOpRescaleUniforms {
vector_float4 color;
float extraAlpha;

int isSrcOpaque;
int isNonPremult;

vector_float4 normScaleFactors;
vector_float4 normOffsets;
};

struct TxtFrameOpConvolveUniforms {
float extraAlpha;
vector_float4 imgEdge;
int kernelSize;
int isEdgeZeroFill;
};

struct TxtFrameOpLookupUniforms {
float extraAlpha;
vector_float4 offset;
int isUseSrcAlpha;
int isNonPremult;
};

struct AnchorData
{
vector_float3 xParams;
@@ -201,6 +201,124 @@ fragment half4 aa_frag_txt(
return half4(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a);
}

fragment half4 frag_txt_op_rescale(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> srcTex [[texture(0)]],
constant TxtFrameOpRescaleUniforms& uniforms [[buffer(1)]],
sampler textureSampler [[sampler(0)]]
) {
float4 srcColor = srcTex.sample(textureSampler, vert.texCoords);
const float srcA = uniforms.isSrcOpaque ? 1 : srcColor.a;

// TODO: check uniforms.isNonPremult and pre-multiply if necessary
return half4(srcColor.r*uniforms.normScaleFactors.r + uniforms.normOffsets.r,
srcColor.g*uniforms.normScaleFactors.g + uniforms.normOffsets.g,
srcColor.b*uniforms.normScaleFactors.b + uniforms.normOffsets.b, srcA*uniforms.extraAlpha);

// NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the
// same here.
//
// GL-shader impl:
//" vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);"
//" %s" // (placeholder for un-premult code: srcColor.rgb /= srcColor.a;)
//" vec4 result = (srcColor * scaleFactors) + offsets;" // rescale source value
//" %s" // (placeholder for re-premult code: result.rgb *= result.a;)
//" gl_FragColor = result * gl_Color;" // modulate with gl_Color in order to apply extra alpha
}

fragment half4 frag_txt_op_convolve(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> srcTex [[texture(0)]],
constant TxtFrameOpConvolveUniforms& uniforms [[buffer(1)]],
const device float3 * kernelVals [[buffer(2)]],
sampler textureSampler [[sampler(0)]]
) {
float4 sum = float4(0, 0, 0, 0);
if (vert.texCoords[0] < uniforms.imgEdge[0]
|| vert.texCoords[1] < uniforms.imgEdge[1]
|| vert.texCoords[0] > uniforms.imgEdge[2]
|| vert.texCoords[1] > uniforms.imgEdge[3]
) {
if (!uniforms.isEdgeZeroFill) {
sum = srcTex.sample(textureSampler, vert.texCoords);
}
}

for (int i = 0; i < uniforms.kernelSize; i++) {
float3 kern = kernelVals[i];
float2 pos = float2(vert.texCoords.x + kern.x, vert.texCoords.y + kern.y);
float4 pixCol = srcTex.sample(textureSampler, pos);
sum.r += kern.z * pixCol.r;
sum.g += kern.z * pixCol.g;
sum.b += kern.z * pixCol.b;
sum.a += kern.z * pixCol.a;
}

return half4(sum.r, sum.g, sum.b, sum.a*uniforms.extraAlpha);

// NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the
// same here.
//
// GL-shader impl:
//" if (any(lessThan(gl_TexCoord[0].st, imgEdge.xy)) ||"
//" any(greaterThan(gl_TexCoord[0].st, imgEdge.zw)))"
//" {"
//" %s" // (placeholder for edge condition code)
//" } else {"
//" sum = vec4(0.0);"
//" for (i = 0; i < MAX_KERNEL_SIZE; i++) {"
//" sum +="
//" kernelVals[i].z *"
//" texture%s(baseImage,"
//" gl_TexCoord[0].st + kernelVals[i].xy);"
//" }"
//" }"
//""
//" gl_FragColor = sum * gl_Color;" // modulate with gl_Color in order to apply extra alpha
}

fragment half4 frag_txt_op_lookup(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> srcTex [[texture(0)]],
texture2d<float, access::sample> lookupTex [[texture(1)]],
constant TxtFrameOpLookupUniforms& uniforms [[buffer(1)]],
sampler textureSampler [[sampler(0)]]
) {
float4 srcColor = srcTex.sample(textureSampler, vert.texCoords);
float4 srcIndex = srcColor - uniforms.offset;
const float2 posR = float2(srcIndex.r, 0.125);
const float2 posG = float2(srcIndex.g, 0.375);
const float2 posB = float2(srcIndex.b, 0.625);

float4 lookupR = lookupTex.sample(textureSampler, posR);
float4 lookupG = lookupTex.sample(textureSampler, posG);
float4 lookupB = lookupTex.sample(textureSampler, posB);

const float a = uniforms.isUseSrcAlpha ? srcColor.a : lookupTex.sample(textureSampler, float2(srcIndex.a, 0.875)).a;

// TODO: check uniforms.isNonPremult and pre-multiply if necessary
return half4(lookupR.a, lookupG.a, lookupB.a, a*uniforms.extraAlpha);

// NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the
// same here.
//
// GL-shader impl:
//" vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);"
//" %s" // (placeholder for un-premult code)
//" vec4 srcIndex = srcColor - offset;" // subtract offset from original index
//
// // use source value as input to lookup table (note that
// // "v" texcoords are hardcoded to hit texel centers of
// // each row/band in texture)
//" vec4 result;"
//" result.r = texture2D(lookupTable, vec2(srcIndex.r, 0.125)).r;"
//" result.g = texture2D(lookupTable, vec2(srcIndex.g, 0.375)).r;"
//" result.b = texture2D(lookupTable, vec2(srcIndex.b, 0.625)).r;"
//" %s" // (placeholder for alpha store code)
//" %s" // (placeholder for re-premult code)
//" gl_FragColor = result * gl_Color;" // modulate with gl_Color in order to apply extra alpha
}

fragment half4 frag_grad(GradShaderInOut in [[stage_in]],
constant GradFrameUniforms& uniforms [[buffer(0)]]) {
float3 v = float3(in.position.x, in.position.y, 1);
@@ -3,8 +3,7 @@

#import <Metal/Metal.h>

#include <jni.h>
#include "MTLSurfaceDataBase.h"
#include "RenderOptions.h"

@class MTLContex;

@@ -56,13 +55,9 @@
isAA:(jboolean)isAA;

// Base method to obtain any MTLRenderCommandEncoder
- (id<MTLRenderCommandEncoder> _Nonnull)
getEncoder:(id<MTLTexture> _Nonnull)dest
isOpaque:(jboolean)isOpaque
isTexture:(jboolean)isTexture
interpolation:(int)interpolation
isAA:(jboolean)isAA
srcFlags:(const SurfaceRasterFlags *_Nullable)srcFlags;
- (id<MTLRenderCommandEncoder> _Nonnull) getEncoder:(id<MTLTexture> _Nonnull)dest
isDestOpaque:(jboolean)isDestOpaque
renderOptions:(const RenderOptions * _Nonnull)renderOptions;

- (id<MTLBlitCommandEncoder> _Nonnull)createBlitEncoder;

0 comments on commit a403550

Please sign in to comment.