Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/java2d/d3d/D3DBufImgOps.cpp
32288 views
/*1* Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <jlong.h>2627#include "D3DBufImgOps.h"28#include "D3DContext.h"29#include "D3DRenderQueue.h"30#include "D3DSurfaceData.h"31#include "GraphicsPrimitiveMgr.h"3233/**************************** ConvolveOp support ****************************/3435/**36* The maximum kernel size supported by the ConvolveOp shader.37*/38#define MAX_KERNEL_SIZE 253940HRESULT41D3DBufImgOps_EnableConvolveOp(D3DContext *d3dc, jlong pSrcOps,42jboolean edgeZeroFill,43jint kernelWidth, jint kernelHeight,44unsigned char *kernel)45{46HRESULT res;47IDirect3DDevice9 *pd3dDevice;48D3DSDOps *srcOps = (D3DSDOps *)jlong_to_ptr(pSrcOps);49jint kernelSize = kernelWidth * kernelHeight;50jint texW, texH;51jfloat xoff, yoff;52jfloat edgeX, edgeY;53jfloat imgEdge[4];54jfloat kernelVals[MAX_KERNEL_SIZE*4];55jint i, j, kIndex;56jint flags = 0;5758J2dTraceLn2(J2D_TRACE_INFO,59"D3DBufImgOps_EnableConvolveOp: kernelW=%d kernelH=%d",60kernelWidth, kernelHeight);6162RETURN_STATUS_IF_NULL(d3dc, E_FAIL);63RETURN_STATUS_IF_NULL(srcOps, E_FAIL);6465d3dc->UpdateState(STATE_CHANGE);6667// texcoords are specified in the range [0,1], so to achieve an68// x/y offset of approximately one pixel we have to normalize69// to that range here70texW = srcOps->pResource->GetDesc()->Width;71texH = srcOps->pResource->GetDesc()->Height;72xoff = 1.0f / texW;73yoff = 1.0f / texH;7475if (edgeZeroFill) {76flags |= CONVOLVE_EDGE_ZERO_FILL;77}78if (kernelWidth == 5 && kernelHeight == 5) {79flags |= CONVOLVE_5X5;80}8182// locate/enable the shader program for the given flags83res = d3dc->EnableConvolveProgram(flags);84RETURN_STATUS_IF_FAILED(res);8586// update the "uniform" image min/max values87// (texcoords are in the range [0,1])88// imgEdge[0] = imgMin.x89// imgEdge[1] = imgMin.y90// imgEdge[2] = imgMax.x91// imgEdge[3] = imgMax.y92edgeX = (kernelWidth/2) * xoff;93edgeY = (kernelHeight/2) * yoff;94imgEdge[0] = edgeX;95imgEdge[1] = edgeY;96imgEdge[2] = (((jfloat)srcOps->width) / texW) - edgeX;97imgEdge[3] = (((jfloat)srcOps->height) / texH) - edgeY;98pd3dDevice = d3dc->Get3DDevice();99pd3dDevice->SetPixelShaderConstantF(0, imgEdge, 1);100101// update the "uniform" kernel offsets and values102kIndex = 0;103for (i = -kernelHeight/2; i < kernelHeight/2+1; i++) {104for (j = -kernelWidth/2; j < kernelWidth/2+1; j++) {105kernelVals[kIndex+0] = j*xoff;106kernelVals[kIndex+1] = i*yoff;107kernelVals[kIndex+2] = NEXT_FLOAT(kernel);108kernelVals[kIndex+3] = 0.0f; // unused109kIndex += 4;110}111}112return pd3dDevice->SetPixelShaderConstantF(1, kernelVals, kernelSize);113}114115HRESULT116D3DBufImgOps_DisableConvolveOp(D3DContext *d3dc)117{118IDirect3DDevice9 *pd3dDevice;119120J2dTraceLn(J2D_TRACE_INFO, "D3DBufImgOps_DisableConvolveOp");121122RETURN_STATUS_IF_NULL(d3dc, E_FAIL);123d3dc->UpdateState(STATE_CHANGE);124125// disable the ConvolveOp shader126pd3dDevice = d3dc->Get3DDevice();127return pd3dDevice->SetPixelShader(NULL);128}129130/**************************** RescaleOp support *****************************/131132HRESULT133D3DBufImgOps_EnableRescaleOp(D3DContext *d3dc,134jboolean nonPremult,135unsigned char *scaleFactors,136unsigned char *offsets)137{138HRESULT res;139IDirect3DDevice9 *pd3dDevice;140jint flags = 0;141142J2dTraceLn(J2D_TRACE_INFO, "D3DBufImgOps_EnableRescaleOp");143144RETURN_STATUS_IF_NULL(d3dc, E_FAIL);145146d3dc->UpdateState(STATE_CHANGE);147148// choose the appropriate shader, depending on the source image149if (nonPremult) {150flags |= RESCALE_NON_PREMULT;151}152153// locate/enable the shader program for the given flags154res = d3dc->EnableRescaleProgram(flags);155RETURN_STATUS_IF_FAILED(res);156157// update the "uniform" scale factor values (note that the Java-level158// dispatching code always passes down 4 values here, regardless of159// the original source image type)160pd3dDevice = d3dc->Get3DDevice();161pd3dDevice->SetPixelShaderConstantF(0, (float *)scaleFactors, 1);162163// update the "uniform" offset values (note that the Java-level164// dispatching code always passes down 4 values here, and that the165// offsets will have already been normalized to the range [0,1])166return pd3dDevice->SetPixelShaderConstantF(1, (float *)offsets, 1);167}168169HRESULT170D3DBufImgOps_DisableRescaleOp(D3DContext *d3dc)171{172IDirect3DDevice9 *pd3dDevice;173174J2dTraceLn(J2D_TRACE_INFO, "D3DBufImgOps_DisableRescaleOp");175176RETURN_STATUS_IF_NULL(d3dc, E_FAIL);177178d3dc->UpdateState(STATE_CHANGE);179180// disable the RescaleOp shader181pd3dDevice = d3dc->Get3DDevice();182return pd3dDevice->SetPixelShader(NULL);183}184185/**************************** LookupOp support ******************************/186187HRESULT188D3DBufImgOps_EnableLookupOp(D3DContext *d3dc,189jboolean nonPremult, jboolean shortData,190jint numBands, jint bandLength, jint offset,191void *tableValues)192{193HRESULT res;194IDirect3DDevice9 *pd3dDevice;195D3DResource *pLutTexRes;196IDirect3DTexture9 *pLutTex;197int bytesPerElem = (shortData ? 2 : 1);198jfloat foffsets[4];199void *bands[4];200int i;201jint flags = 0;202203for (i = 0; i < 4; i++) {204bands[i] = NULL;205}206J2dTraceLn4(J2D_TRACE_INFO,207"D3DBufImgOps_EnableLookupOp: short=%d num=%d len=%d off=%d",208shortData, numBands, bandLength, offset);209210RETURN_STATUS_IF_NULL(d3dc, E_FAIL);211212d3dc->UpdateState(STATE_CHANGE);213214// choose the appropriate shader, depending on the source image215// and the number of bands involved216if (numBands != 4) {217flags |= LOOKUP_USE_SRC_ALPHA;218}219if (nonPremult) {220flags |= LOOKUP_NON_PREMULT;221}222223// locate/enable the shader program for the given flags224res = d3dc->EnableLookupProgram(flags);225RETURN_STATUS_IF_FAILED(res);226227// update the "uniform" offset value228for (i = 0; i < 4; i++) {229foffsets[i] = offset / 255.0f;230}231pd3dDevice = d3dc->Get3DDevice();232pd3dDevice->SetPixelShaderConstantF(0, foffsets, 1);233234res = d3dc->GetResourceManager()->GetLookupOpLutTexture(&pLutTexRes);235RETURN_STATUS_IF_FAILED(res);236pLutTex = pLutTexRes->GetTexture();237238// update the lookup table with the user-provided values239if (numBands == 1) {240// replicate the single band for R/G/B; alpha band is unused241for (i = 0; i < 3; i++) {242bands[i] = tableValues;243}244bands[3] = NULL;245} else if (numBands == 3) {246// user supplied band for each of R/G/B; alpha band is unused247for (i = 0; i < 3; i++) {248bands[i] = PtrAddBytes(tableValues, i*bandLength*bytesPerElem);249}250bands[3] = NULL;251} else if (numBands == 4) {252// user supplied band for each of R/G/B/A253for (i = 0; i < 4; i++) {254bands[i] = PtrAddBytes(tableValues, i*bandLength*bytesPerElem);255}256}257258// upload the bands one row at a time into our lookup table texture259D3DLOCKED_RECT lockedRect;260res = pLutTex->LockRect(0, &lockedRect, NULL, D3DLOCK_NOSYSLOCK);261RETURN_STATUS_IF_FAILED(res);262263jushort *pBase = (jushort*)lockedRect.pBits;264for (i = 0; i < 4; i++) {265jushort *pDst;266if (bands[i] == NULL) {267continue;268}269pDst = pBase + (i * 256);270if (shortData) {271memcpy(pDst, bands[i], bandLength*sizeof(jushort));272} else {273int j;274jubyte *pSrc = (jubyte *)bands[i];275for (j = 0; j < bandLength; j++) {276pDst[j] = (jushort)(pSrc[j] << 8);277}278}279}280pLutTex->UnlockRect(0);281282// bind the lookup table to texture unit 1 and enable texturing283res = d3dc->SetTexture(pLutTex, 1);284pd3dDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);285pd3dDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);286pd3dDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);287pd3dDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);288return res;289}290291HRESULT292D3DBufImgOps_DisableLookupOp(D3DContext *d3dc)293{294IDirect3DDevice9 *pd3dDevice;295296J2dTraceLn(J2D_TRACE_INFO, "D3DBufImgOps_DisableLookupOp");297298RETURN_STATUS_IF_NULL(d3dc, E_FAIL);299300d3dc->UpdateState(STATE_CHANGE);301302// disable the LookupOp shader303pd3dDevice = d3dc->Get3DDevice();304pd3dDevice->SetPixelShader(NULL);305306// disable the lookup table on texture unit 1307return d3dc->SetTexture(NULL, 1);308}309310311