Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8256331: Lanai: DrawImage/IncorrectAlphaSurface2SW fails
  • Loading branch information
Alexey Ushakov committed Nov 17, 2020
1 parent 501ace0 commit cf94b38ac5d0de728674aef2a77ad36e6ee6796e
@@ -112,7 +112,6 @@ struct TxtFrameUniforms {
vector_float4 color;
int mode; // NOTE: consider to use bit fields
int isSrcOpaque;
int isSrcPremult;
int isDstOpaque;
float extraAlpha;
};
@@ -244,10 +244,6 @@ fragment half4 frag_txt(
return half4(c.r, c.g, c.b , c.a);
}

if (uniforms.isSrcPremult) {
pixelColor.rgb /= srcA;
}

return half4(pixelColor.r,
pixelColor.g,
pixelColor.b, srcA)*uniforms.extraAlpha;
@@ -649,6 +649,18 @@ jboolean clipDestCoords(
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
}

void copyFromMTLBuffer(void *pDst, id<MTLBuffer> srcBuf, jint offset, jint len, BOOL convertFromArgbPre) {
char *pSrc = (char*)srcBuf.contents + offset;
if (convertFromArgbPre) {
jint pixelLen = len>>2;
for (int i = 0; i < pixelLen; i++) {
LoadIntArgbPreTo1IntArgb((jint*)pSrc, 0, i, ((jint*)pDst)[i]);
}
} else {
memcpy(pDst, pSrc, len);
}
}

/**
* Specialized blit method for copying a native MTL "Surface" (pbuffer,
* window, etc.) to a system memory ("Sw") surface.
@@ -719,7 +731,7 @@ jboolean clipDestCoords(
// Metal texture is (0,0) at left-top
srcx = srcOps->xOffset + srcx;
srcy = srcOps->yOffset + srcy;
const int srcLength = width * height * 4; // NOTE: assume that src format is MTLPixelFormatBGRA8Unorm
const int byteLength = width * height * 4; // NOTE: assume that src format is MTLPixelFormatBGRA8Unorm

// Create MTLBuffer (or use static)
MTLRasterFormatInfo rfi = RasterFormatInfos[dsttype];
@@ -771,27 +783,28 @@ jboolean clipDestCoords(
toBuffer:mtlbuf
destinationOffset:0 /*offset already taken in: pDst = PtrAddBytes(pDst, dstx * dstInfo.pixelStride)*/
destinationBytesPerRow:width*4
destinationBytesPerImage:width * height*4];
destinationBytesPerImage:byteLength];
[blitEncoder endEncoding];

// Commit and wait for reading complete
[cb commit];
[cb waitUntilCompleted];

// Perform conversion if necessary
BOOL convertFromPre = !RasterFormatInfos[dsttype].isPremult && !srcOps->isOpaque;
if (directCopy) {
if ((dstInfo.scanStride == width * dstInfo.pixelStride) &&
(height == (dstInfo.bounds.y2 - dstInfo.bounds.y1))) {
// mtlbuf.contents have same dimensions as of pDst
memcpy(pDst, mtlbuf.contents, srcLength);
copyFromMTLBuffer(pDst, mtlbuf, 0, byteLength, convertFromPre);
} else {
// mtlbuf.contents have smaller dimensions than pDst
// copy each row from mtlbuf.contents at appropriate position in pDst
// Note : pDst is already addjusted for offsets using PtrAddBytes above

int rowSize = width * dstInfo.pixelStride;
for (int y = 0; y < height; y++) {
memcpy(pDst, mtlbuf.contents + (y * rowSize), rowSize);
copyFromMTLBuffer(pDst, mtlbuf, y * rowSize, rowSize, convertFromPre);
pDst = PtrAddBytes(pDst, dstInfo.scanStride);
}
}
@@ -867,9 +867,7 @@ static void setTxtUniforms(
id<MTLRenderCommandEncoder> encoder, int color, int mode, int interpolation, bool repeat, jfloat extraAlpha,
const SurfaceRasterFlags * srcFlags, const SurfaceRasterFlags * dstFlags
) {
struct TxtFrameUniforms uf = {
RGBA_TO_V4(color), mode, srcFlags->isOpaque, srcFlags->isPremultiplied,
dstFlags->isOpaque, extraAlpha};
struct TxtFrameUniforms uf = {RGBA_TO_V4(color), mode, srcFlags->isOpaque, dstFlags->isOpaque, extraAlpha};
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];

setSampler(encoder, interpolation, repeat);

0 comments on commit cf94b38

Please sign in to comment.