430N/A/*
2362N/A * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
430N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
430N/A *
430N/A * This code is free software; you can redistribute it and/or modify it
430N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
430N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
430N/A *
430N/A * This code is distributed in the hope that it will be useful, but WITHOUT
430N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
430N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
430N/A * version 2 for more details (a copy is included in the LICENSE file that
430N/A * accompanied this code).
430N/A *
430N/A * You should have received a copy of the GNU General Public License version
430N/A * 2 along with this work; if not, write to the Free Software Foundation,
430N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
430N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
430N/A */
430N/A
862N/A#include "D3DPipeline.h"
430N/A#include <malloc.h>
430N/A#include "sun_java2d_pipe_BufferedOpCodes.h"
430N/A
430N/A#include "jlong.h"
430N/A#include "D3DBlitLoops.h"
430N/A#include "D3DBufImgOps.h"
430N/A#include "D3DPipelineManager.h"
430N/A#include "D3DContext.h"
430N/A#include "D3DMaskBlit.h"
430N/A#include "D3DMaskFill.h"
430N/A#include "D3DPaints.h"
430N/A#include "D3DRenderQueue.h"
430N/A#include "D3DRenderer.h"
430N/A#include "D3DSurfaceData.h"
430N/A#include "D3DTextRenderer.h"
430N/A#include "Trace.h"
430N/A#include "awt_Toolkit.h"
430N/A
430N/ABOOL DWMIsCompositionEnabled();
430N/A
430N/A/**
430N/A * References to the "current" context and destination surface.
430N/A */
430N/Astatic D3DContext *d3dc = NULL;
430N/Astatic D3DSDOps *dstOps = NULL;
430N/Astatic BOOL bLostDevices = FALSE;
430N/A
430N/Atypedef struct {
430N/A byte *buffer;
430N/A int limit;
430N/A jobject runnable;
430N/A} FlushBufferStruct;
430N/A
430N/AHRESULT
430N/AD3DRQ_SwapBuffers(D3DPipelineManager *pMgr, D3DSDOps *d3dsdo,
430N/A int x1, int y1, int x2, int y2)
430N/A{
430N/A HRESULT res;
430N/A D3DContext *pCtx;
430N/A IDirect3DSwapChain9 *pSwapChain;
430N/A RECT srcRect, dstRect, *pSrcRect, *pDstRect;
430N/A
430N/A J2dTraceLn(J2D_TRACE_INFO, "D3DRQ_SwapBuffers");
430N/A J2dTraceLn4(J2D_TRACE_VERBOSE, " x1=%d y1=%d x2=%d y2=%d",
430N/A x1, y1, x2, y2);
430N/A
430N/A RETURN_STATUS_IF_NULL(d3dsdo, E_FAIL);
430N/A RETURN_STATUS_IF_NULL(d3dsdo->pResource, E_FAIL);
430N/A RETURN_STATUS_IF_NULL(pSwapChain=d3dsdo->pResource->GetSwapChain(), E_FAIL);
430N/A
430N/A pCtx = D3DRQ_GetCurrentContext();
430N/A if (pCtx != NULL) {
430N/A // flush the current vertex queue here, just in case
430N/A res = d3dc->FlushVertexQueue();
430N/A D3DRQ_MarkLostIfNeeded(res, dstOps);
430N/A pCtx = NULL;
430N/A }
430N/A // end scene for this destination
430N/A res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx);
430N/A RETURN_STATUS_IF_FAILED(res);
430N/A
430N/A pCtx->EndScene();
430N/A
430N/A // This is a workaround for what apparently is a DWM bug.
430N/A // If the dimensions of the back-buffer don't match the dimensions of
430N/A // the window, Present() will flash the whole window with black.
430N/A // The workaround is to detect this situation and not do a present.
430N/A // It is ok to do so since a repaint event is coming due to the resize that
430N/A // just happened.
430N/A //
430N/A // REMIND: this will need to be updated if we switch to creating
430N/A // back-buffers of the size of the client area instead of the whole window
430N/A // (use GetClientRect() instead of GetWindowRect()).
430N/A if (DWMIsCompositionEnabled()) {
430N/A RECT r;
430N/A D3DPRESENT_PARAMETERS params;
430N/A
430N/A pSwapChain->GetPresentParameters(&params);
430N/A GetWindowRect(params.hDeviceWindow, &r);
430N/A int ww = r.right - r.left;
430N/A int wh = r.bottom - r.top;
430N/A if (ww != params.BackBufferWidth || wh != params.BackBufferHeight) {
430N/A J2dTraceLn4(J2D_TRACE_WARNING,
430N/A "D3DRQ_SwapBuffers: surface/window dimensions mismatch: "\
430N/A "win: w=%d h=%d, bb: w=%d h=%d",
430N/A ww, wh, params.BackBufferWidth, params.BackBufferHeight);
430N/A
430N/A return S_OK;
430N/A }
430N/A }
430N/A
430N/A if (d3dsdo->swapEffect == D3DSWAPEFFECT_COPY) {
430N/A J2dTraceLn(J2D_TRACE_VERBOSE, " D3DSWAPEFFECT_COPY");
430N/A if (x1 < 0) x1 = 0;
430N/A if (y1 < 0) y1 = 0;
430N/A if (x2 > d3dsdo->width) x2 = d3dsdo->width;
430N/A if (y2 > d3dsdo->height) y2 = d3dsdo->height;
430N/A if (x2 <= x1 || y2 <= y1) {
430N/A // nothing to present
430N/A return S_OK;
430N/A }
430N/A srcRect.left = x1;
430N/A srcRect.top = y1;
430N/A srcRect.right = x2;
430N/A srcRect.bottom = y2;
430N/A
430N/A dstRect = srcRect;
430N/A
430N/A pSrcRect = &srcRect;
430N/A pDstRect = &dstRect;
430N/A // only offset in windowed mode
430N/A if (pCtx!= NULL && pCtx->GetPresentationParams()->Windowed) {
430N/A OffsetRect(pDstRect, d3dsdo->xoff, d3dsdo->yoff);
430N/A } else {
430N/A // some boards (Nvidia) have problems with copy strategy and
430N/A // non-null src/dest rectangles in fs mode; unfortunately this
430N/A // means that we'll paint over fs window decorations
430N/A pSrcRect = NULL;
430N/A pDstRect = NULL;
430N/A }
430N/A } else {
430N/A if (d3dsdo->swapEffect == D3DSWAPEFFECT_FLIP) {
430N/A J2dTraceLn(J2D_TRACE_VERBOSE, " D3DSWAPEFFECT_FLIP");
430N/A } else {
430N/A J2dTraceLn(J2D_TRACE_VERBOSE, " D3DSWAPEFFECT_DISCARD");
430N/A }
430N/A // src and dest rectangles must be NULL for FLIP/DISCARD
430N/A pSrcRect = NULL;
430N/A pDstRect = NULL;
430N/A }
430N/A
430N/A res = pSwapChain->Present(pSrcRect, pDstRect, 0, NULL, 0);
430N/A res = D3DRQ_MarkLostIfNeeded(res, d3dsdo);
430N/A
430N/A return res;
430N/A}
430N/A
430N/AHRESULT
430N/AD3DRQ_MarkLostIfNeeded(HRESULT res, D3DSDOps *d3dops)
430N/A{
430N/A if (res == D3DERR_DEVICELOST || res == D3DERR_DEVICENOTRESET) {
430N/A D3DContext *pCtx;
430N/A
430N/A J2dTraceLn(J2D_TRACE_WARNING, "D3DRQ_MarkLostIfNeeded: device lost");
430N/A bLostDevices = TRUE;
430N/A
430N/A // only mark surfaces belonging to the lost device
430N/A if (d3dops != NULL &&
430N/A SUCCEEDED(res = D3DPipelineManager::GetInstance()->
430N/A GetD3DContext(d3dops->adapter, &pCtx)))
430N/A {
430N/A IDirect3DDevice9 *pd3dDevice = pCtx->Get3DDevice();
430N/A if (pd3dDevice) {
430N/A HRESULT res1 = pd3dDevice->TestCooperativeLevel();
430N/A if (res1 != D3DERR_DEVICELOST && res1 != D3DERR_DEVICENOTRESET){
430N/A // this surface's device is not lost, do not mark it
430N/A return res;
430N/A }
430N/A }
430N/A }
430N/A D3DSD_MarkLost(d3dops);
430N/A }
430N/A return res;
430N/A}
430N/A
430N/Avoid D3DRQ_FlushBuffer(void *pParam)
430N/A{
430N/A FlushBufferStruct *pFlush = (FlushBufferStruct*)pParam;
430N/A JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
430N/A unsigned char *b, *end;
430N/A int limit;
430N/A HRESULT res = S_OK;
430N/A BOOL bSync = FALSE;
430N/A
430N/A b = pFlush->buffer;
430N/A limit = pFlush->limit;
430N/A J2dTraceLn1(J2D_TRACE_INFO, "D3DRQ_flushBuffer: limit=%d", limit);
430N/A
430N/A end = b + limit;
430N/A
430N/A D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
430N/A if (pMgr == NULL) {
430N/A J2dRlsTraceLn(J2D_TRACE_WARNING, "D3DRQ_flushBuffer: null manager");
430N/A return;
430N/A }
430N/A
430N/A if (bLostDevices) {
430N/A if (SUCCEEDED(res = pMgr->HandleLostDevices())) {
430N/A bLostDevices = FALSE;
430N/A }
430N/A }
430N/A
430N/A while (b < end) {
430N/A jint opcode = NEXT_INT(b);
430N/A
430N/A J2dTraceLn1(J2D_TRACE_VERBOSE, "D3DRQ_flushBuffer: opcode=%d", opcode);
430N/A
430N/A switch (opcode) {
430N/A
430N/A // draw ops
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
430N/A {
430N/A jint x1 = NEXT_INT(b);
430N/A jint y1 = NEXT_INT(b);
430N/A jint x2 = NEXT_INT(b);
430N/A jint y2 = NEXT_INT(b);
430N/A
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_DrawLine(d3dc, x1, y1, x2, y2);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
430N/A {
430N/A jint x = NEXT_INT(b);
430N/A jint y = NEXT_INT(b);
430N/A jint w = NEXT_INT(b);
430N/A jint h = NEXT_INT(b);
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_DrawRect(d3dc, x, y, w, h);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY:
430N/A {
430N/A jint nPoints = NEXT_INT(b);
430N/A jboolean isClosed = NEXT_BOOLEAN(b);
430N/A jint transX = NEXT_INT(b);
430N/A jint transY = NEXT_INT(b);
430N/A jint *xPoints = (jint *)b;
430N/A jint *yPoints = ((jint *)b) + nPoints;
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_DrawPoly(d3dc, nPoints, isClosed,
430N/A transX, transY,
430N/A xPoints, yPoints);
430N/A SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL:
430N/A {
430N/A jint x = NEXT_INT(b);
430N/A jint y = NEXT_INT(b);
430N/A
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_DrawLine(d3dc, x, y, x, y);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:
430N/A {
430N/A jint count = NEXT_INT(b);
430N/A res = D3DRenderer_DrawScanlines(d3dc, count, (jint *)b);
430N/A SKIP_BYTES(b, count * BYTES_PER_SCANLINE);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
430N/A {
430N/A jfloat x11 = NEXT_FLOAT(b);
430N/A jfloat y11 = NEXT_FLOAT(b);
430N/A jfloat dx21 = NEXT_FLOAT(b);
430N/A jfloat dy21 = NEXT_FLOAT(b);
430N/A jfloat dx12 = NEXT_FLOAT(b);
430N/A jfloat dy12 = NEXT_FLOAT(b);
430N/A jfloat lwr21 = NEXT_FLOAT(b);
430N/A jfloat lwr12 = NEXT_FLOAT(b);
430N/A
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_DrawParallelogram(d3dc,
430N/A x11, y11,
430N/A dx21, dy21,
430N/A dx12, dy12,
430N/A lwr21, lwr12);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM:
430N/A {
430N/A jfloat x11 = NEXT_FLOAT(b);
430N/A jfloat y11 = NEXT_FLOAT(b);
430N/A jfloat dx21 = NEXT_FLOAT(b);
430N/A jfloat dy21 = NEXT_FLOAT(b);
430N/A jfloat dx12 = NEXT_FLOAT(b);
430N/A jfloat dy12 = NEXT_FLOAT(b);
430N/A jfloat lwr21 = NEXT_FLOAT(b);
430N/A jfloat lwr12 = NEXT_FLOAT(b);
430N/A
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_DrawAAParallelogram(d3dc,
430N/A x11, y11,
430N/A dx21, dy21,
430N/A dx12, dy12,
430N/A lwr21, lwr12);
430N/A }
430N/A break;
430N/A
430N/A // fill ops
430N/A case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:
430N/A {
430N/A jint x = NEXT_INT(b);
430N/A jint y = NEXT_INT(b);
430N/A jint w = NEXT_INT(b);
430N/A jint h = NEXT_INT(b);
430N/A
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_FillRect(d3dc, x, y, w, h);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
430N/A {
430N/A jfloat x11 = NEXT_FLOAT(b);
430N/A jfloat y11 = NEXT_FLOAT(b);
430N/A jfloat dx21 = NEXT_FLOAT(b);
430N/A jfloat dy21 = NEXT_FLOAT(b);
430N/A jfloat dx12 = NEXT_FLOAT(b);
430N/A jfloat dy12 = NEXT_FLOAT(b);
430N/A
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_FillParallelogram(d3dc,
430N/A x11, y11,
430N/A dx21, dy21,
430N/A dx12, dy12);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:
430N/A {
430N/A jfloat x11 = NEXT_FLOAT(b);
430N/A jfloat y11 = NEXT_FLOAT(b);
430N/A jfloat dx21 = NEXT_FLOAT(b);
430N/A jfloat dy21 = NEXT_FLOAT(b);
430N/A jfloat dx12 = NEXT_FLOAT(b);
430N/A jfloat dy12 = NEXT_FLOAT(b);
430N/A
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = D3DRenderer_FillAAParallelogram(d3dc,
430N/A x11, y11,
430N/A dx21, dy21,
430N/A dx12, dy12);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:
430N/A {
430N/A jint count = NEXT_INT(b);
430N/A res = D3DRenderer_FillSpans(d3dc, count, (jint *)b);
430N/A SKIP_BYTES(b, count * BYTES_PER_SPAN);
430N/A }
430N/A break;
430N/A
430N/A // text-related ops
430N/A case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST:
430N/A {
430N/A jint numGlyphs = NEXT_INT(b);
430N/A jint packedParams = NEXT_INT(b);
430N/A jfloat glyphListOrigX = NEXT_FLOAT(b);
430N/A jfloat glyphListOrigY = NEXT_FLOAT(b);
430N/A jboolean usePositions = EXTRACT_BOOLEAN(packedParams,
430N/A OFFSET_POSITIONS);
430N/A jboolean subPixPos = EXTRACT_BOOLEAN(packedParams,
430N/A OFFSET_SUBPIXPOS);
430N/A jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams,
430N/A OFFSET_RGBORDER);
430N/A jint lcdContrast = EXTRACT_BYTE(packedParams,
430N/A OFFSET_CONTRAST);
430N/A unsigned char *images = b;
430N/A unsigned char *positions;
430N/A jint bytesPerGlyph;
430N/A if (usePositions) {
430N/A positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE);
430N/A bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH;
430N/A } else {
430N/A positions = NULL;
430N/A bytesPerGlyph = BYTES_PER_GLYPH_IMAGE;
430N/A }
430N/A res = D3DTR_DrawGlyphList(d3dc, dstOps,
430N/A numGlyphs, usePositions,
430N/A subPixPos, rgbOrder, lcdContrast,
430N/A glyphListOrigX, glyphListOrigY,
430N/A images, positions);
430N/A SKIP_BYTES(b, numGlyphs * bytesPerGlyph);
430N/A }
430N/A break;
430N/A
430N/A // copy-related ops
430N/A case sun_java2d_pipe_BufferedOpCodes_COPY_AREA:
430N/A {
430N/A jint x = NEXT_INT(b);
430N/A jint y = NEXT_INT(b);
430N/A jint w = NEXT_INT(b);
430N/A jint h = NEXT_INT(b);
430N/A jint dx = NEXT_INT(b);
430N/A jint dy = NEXT_INT(b);
430N/A res = D3DBlitLoops_CopyArea(env, d3dc, dstOps,
430N/A x, y, w, h, dx, dy);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_BLIT:
430N/A {
430N/A jint packedParams = NEXT_INT(b);
430N/A jint sx1 = NEXT_INT(b);
430N/A jint sy1 = NEXT_INT(b);
430N/A jint sx2 = NEXT_INT(b);
430N/A jint sy2 = NEXT_INT(b);
430N/A jdouble dx1 = NEXT_DOUBLE(b);
430N/A jdouble dy1 = NEXT_DOUBLE(b);
430N/A jdouble dx2 = NEXT_DOUBLE(b);
430N/A jdouble dy2 = NEXT_DOUBLE(b);
430N/A jlong pSrc = NEXT_LONG(b);
430N/A jlong pDst = NEXT_LONG(b);
430N/A jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT);
430N/A jboolean texture = EXTRACT_BOOLEAN(packedParams,
430N/A OFFSET_TEXTURE);
430N/A jboolean rtt = EXTRACT_BOOLEAN(packedParams,
430N/A OFFSET_RTT);
430N/A jboolean xform = EXTRACT_BOOLEAN(packedParams,
430N/A OFFSET_XFORM);
430N/A jboolean isoblit = EXTRACT_BOOLEAN(packedParams,
430N/A OFFSET_ISOBLIT);
430N/A if (isoblit) {
430N/A res = D3DBlitLoops_IsoBlit(env, d3dc, pSrc, pDst,
430N/A xform, hint, texture, rtt,
430N/A sx1, sy1, sx2, sy2,
430N/A dx1, dy1, dx2, dy2);
430N/A D3DRQ_MarkLostIfNeeded(res, (D3DSDOps*)pSrc);
430N/A } else {
430N/A jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE);
430N/A res = D3DBlitLoops_Blit(env, d3dc, pSrc, pDst,
430N/A xform, hint, srctype, texture,
430N/A sx1, sy1, sx2, sy2,
430N/A dx1, dy1, dx2, dy2);
430N/A }
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT:
430N/A {
430N/A jint sx = NEXT_INT(b);
430N/A jint sy = NEXT_INT(b);
430N/A jint dx = NEXT_INT(b);
430N/A jint dy = NEXT_INT(b);
430N/A jint w = NEXT_INT(b);
430N/A jint h = NEXT_INT(b);
430N/A jint dsttype = NEXT_INT(b);
430N/A jlong pSrc = NEXT_LONG(b);
430N/A jlong pDst = NEXT_LONG(b);
430N/A res = D3DBlitLoops_SurfaceToSwBlit(env, d3dc,
430N/A pSrc, pDst, dsttype,
430N/A sx, sy, dx, dy, w, h);
430N/A D3DRQ_MarkLostIfNeeded(res, (D3DSDOps*)pSrc);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_MASK_FILL:
430N/A {
430N/A jint x = NEXT_INT(b);
430N/A jint y = NEXT_INT(b);
430N/A jint w = NEXT_INT(b);
430N/A jint h = NEXT_INT(b);
430N/A jint maskoff = NEXT_INT(b);
430N/A jint maskscan = NEXT_INT(b);
430N/A jint masklen = NEXT_INT(b);
430N/A unsigned char *pMask = (masklen > 0) ? b : NULL;
430N/A res = D3DMaskFill_MaskFill(d3dc, x, y, w, h,
430N/A maskoff, maskscan, masklen, pMask);
430N/A SKIP_BYTES(b, masklen);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT:
430N/A {
430N/A jint dstx = NEXT_INT(b);
430N/A jint dsty = NEXT_INT(b);
430N/A jint width = NEXT_INT(b);
430N/A jint height = NEXT_INT(b);
430N/A jint masklen = width * height * sizeof(jint);
430N/A res = D3DMaskBlit_MaskBlit(env, d3dc,
430N/A dstx, dsty, width, height, b);
430N/A SKIP_BYTES(b, masklen);
430N/A }
430N/A break;
430N/A
430N/A // state-related ops
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP:
430N/A {
430N/A jint x1 = NEXT_INT(b);
430N/A jint y1 = NEXT_INT(b);
430N/A jint x2 = NEXT_INT(b);
430N/A jint y2 = NEXT_INT(b);
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = d3dc->SetRectClip(x1, y1, x2, y2);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:
430N/A {
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = d3dc->BeginShapeClip();
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:
430N/A {
430N/A jint count = NEXT_INT(b);
430N/A res = D3DRenderer_FillSpans(d3dc, count, (jint *)b);
430N/A SKIP_BYTES(b, count * BYTES_PER_SPAN);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:
430N/A {
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = d3dc->EndShapeClip();
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:
430N/A {
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = d3dc->ResetClip();
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:
430N/A {
430N/A jint rule = NEXT_INT(b);
430N/A jfloat extraAlpha = NEXT_FLOAT(b);
430N/A jint flags = NEXT_INT(b);
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = d3dc->SetAlphaComposite(rule, extraAlpha, flags);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
430N/A {
430N/A jint xorPixel = NEXT_INT(b);
430N/A// res = d3dc->SetXorComposite(d3dc, xorPixel);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
430N/A {
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = d3dc->ResetComposite();
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:
430N/A {
430N/A jdouble m00 = NEXT_DOUBLE(b);
430N/A jdouble m10 = NEXT_DOUBLE(b);
430N/A jdouble m01 = NEXT_DOUBLE(b);
430N/A jdouble m11 = NEXT_DOUBLE(b);
430N/A jdouble m02 = NEXT_DOUBLE(b);
430N/A jdouble m12 = NEXT_DOUBLE(b);
430N/A res = d3dc->SetTransform(m00, m10, m01, m11, m02, m12);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:
430N/A {
430N/A CONTINUE_IF_NULL(d3dc);
430N/A res = d3dc->ResetTransform();
430N/A }
430N/A break;
430N/A
430N/A // context-related ops
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
430N/A {
430N/A jlong pSrc = NEXT_LONG(b);
430N/A jlong pDst = NEXT_LONG(b);
430N/A D3DContext *oldd3dc = NULL;
430N/A if (d3dc != NULL) {
430N/A oldd3dc = d3dc;
430N/A d3dc = NULL;
430N/A oldd3dc->UpdateState(STATE_CHANGE);
430N/A }
430N/A dstOps = (D3DSDOps *)jlong_to_ptr(pDst);
430N/A res = pMgr->GetD3DContext(dstOps->adapter, &d3dc);
430N/A if (FAILED(res)) {
430N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
430N/A "D3DRQ_FlushBuffer: failed to get context");
430N/A D3DRQ_ResetCurrentContextAndDestination();
430N/A break;
430N/A }
430N/A // REMIND: we may also want to do EndScene on each
430N/A // render target change so that the GPU can go work on
430N/A // whatever is already in the queue
430N/A if (oldd3dc != d3dc && oldd3dc != NULL) {
430N/A res = oldd3dc->EndScene();
430N/A }
430N/A CONTINUE_IF_NULL(dstOps->pResource);
430N/A res = d3dc->SetRenderTarget(dstOps->pResource->GetSurface());
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:
430N/A {
430N/A jint screen = NEXT_INT(b);
430N/A jint adapter = pMgr->GetAdapterOrdinalForScreen(screen);
430N/A D3DContext *oldd3dc = NULL;
430N/A
430N/A if (d3dc != NULL) {
430N/A oldd3dc = d3dc;
430N/A d3dc = NULL;
430N/A }
430N/A res = pMgr->GetD3DContext(adapter, &d3dc);
430N/A if (FAILED(res)) {
430N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
430N/A "D3DRQ_FlushBuffer: failed to get context");
430N/A D3DRQ_ResetCurrentContextAndDestination();
430N/A } else if (oldd3dc != d3dc && oldd3dc != NULL) {
430N/A res = oldd3dc->EndScene();
430N/A }
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
430N/A {
430N/A jlong pData = NEXT_LONG(b);
430N/A D3DSDOps *d3dsdo = (D3DSDOps *)jlong_to_ptr(pData);
430N/A D3DSD_Flush(d3dsdo);
430N/A if (dstOps == d3dsdo) {
430N/A dstOps = NULL;
430N/A }
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
430N/A {
430N/A jlong pData = NEXT_LONG(b);
430N/A D3DSDOps *d3dsdo = (D3DSDOps *)jlong_to_ptr(pData);
430N/A D3DSD_Flush(d3dsdo);
430N/A if (dstOps == d3dsdo) {
430N/A dstOps = NULL;
430N/A }
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
430N/A {
430N/A jlong pConfigInfo = NEXT_LONG(b);
430N/A CONTINUE_IF_NULL(d3dc);
430N/A // REMIND: does this need to be implemented for D3D?
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:
430N/A {
430N/A // flush just in case there are any pending operations in
430N/A // the hardware pipe
430N/A if (d3dc != NULL) {
430N/A res = d3dc->EndScene();
430N/A }
430N/A
430N/A // invalidate the references to the current context and
430N/A // destination surface that are maintained at the native level
430N/A D3DRQ_ResetCurrentContextAndDestination();
430N/A }
430N/A break;
430N/A
430N/A case sun_java2d_pipe_BufferedOpCodes_SYNC:
430N/A {
430N/A bSync = TRUE;
430N/A }
430N/A break;
430N/A
430N/A case sun_java2d_pipe_BufferedOpCodes_RESTORE_DEVICES:
430N/A {
430N/A J2dTraceLn(J2D_TRACE_INFO, "D3DRQ_FlushBuffer: RESTORE_DEVICES");
430N/A if (SUCCEEDED(res = pMgr->HandleLostDevices())) {
430N/A bLostDevices = FALSE;
430N/A } else {
430N/A bLostDevices = TRUE;
430N/A }
430N/A }
430N/A break;
430N/A
430N/A case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE:
430N/A {
430N/A CONTINUE_IF_NULL(d3dc);
430N/A
430N/A res = d3dc->SaveState();
430N/A }
430N/A break;
430N/A
430N/A case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE:
430N/A {
430N/A CONTINUE_IF_NULL(d3dc);
430N/A
430N/A res = d3dc->RestoreState();
430N/A }
430N/A break;
430N/A
430N/A // multibuffering ops
430N/A case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS:
430N/A {
430N/A jlong sdo = NEXT_LONG(b);
430N/A jint x1 = NEXT_INT(b);
430N/A jint y1 = NEXT_INT(b);
430N/A jint x2 = NEXT_INT(b);
430N/A jint y2 = NEXT_INT(b);
430N/A
430N/A res = D3DRQ_SwapBuffers(pMgr, (D3DSDOps *)jlong_to_ptr(sdo),
430N/A x1, y1, x2, y2);
430N/A }
430N/A break;
430N/A
430N/A // special no-op (mainly used for achieving 8-byte alignment)
430N/A case sun_java2d_pipe_BufferedOpCodes_NOOP:
430N/A break;
430N/A
430N/A // paint-related ops
430N/A case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT:
430N/A {
430N/A res = D3DPaints_ResetPaint(d3dc);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
430N/A {
430N/A jint pixel = NEXT_INT(b);
430N/A res = D3DPaints_SetColor(d3dc, pixel);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:
430N/A {
430N/A jboolean useMask= NEXT_BOOLEAN(b);
430N/A jboolean cyclic = NEXT_BOOLEAN(b);
430N/A jdouble p0 = NEXT_DOUBLE(b);
430N/A jdouble p1 = NEXT_DOUBLE(b);
430N/A jdouble p3 = NEXT_DOUBLE(b);
430N/A jint pixel1 = NEXT_INT(b);
430N/A jint pixel2 = NEXT_INT(b);
430N/A res = D3DPaints_SetGradientPaint(d3dc, useMask, cyclic,
430N/A p0, p1, p3,
430N/A pixel1, pixel2);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:
430N/A {
430N/A jboolean useMask = NEXT_BOOLEAN(b);
430N/A jboolean linear = NEXT_BOOLEAN(b);
430N/A jint cycleMethod = NEXT_INT(b);
430N/A jint numStops = NEXT_INT(b);
430N/A jfloat p0 = NEXT_FLOAT(b);
430N/A jfloat p1 = NEXT_FLOAT(b);
430N/A jfloat p3 = NEXT_FLOAT(b);
430N/A void *fractions, *pixels;
430N/A fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));
430N/A pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
430N/A res = D3DPaints_SetLinearGradientPaint(d3dc, dstOps,
430N/A useMask, linear,
430N/A cycleMethod, numStops,
430N/A p0, p1, p3,
430N/A fractions, pixels);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:
430N/A {
430N/A jboolean useMask = NEXT_BOOLEAN(b);
430N/A jboolean linear = NEXT_BOOLEAN(b);
430N/A jint numStops = NEXT_INT(b);
430N/A jint cycleMethod = NEXT_INT(b);
430N/A jfloat m00 = NEXT_FLOAT(b);
430N/A jfloat m01 = NEXT_FLOAT(b);
430N/A jfloat m02 = NEXT_FLOAT(b);
430N/A jfloat m10 = NEXT_FLOAT(b);
430N/A jfloat m11 = NEXT_FLOAT(b);
430N/A jfloat m12 = NEXT_FLOAT(b);
430N/A jfloat focusX = NEXT_FLOAT(b);
430N/A void *fractions, *pixels;
430N/A fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));
430N/A pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
430N/A res = D3DPaints_SetRadialGradientPaint(d3dc, dstOps,
430N/A useMask, linear,
430N/A cycleMethod, numStops,
430N/A m00, m01, m02,
430N/A m10, m11, m12,
430N/A focusX,
430N/A fractions, pixels);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:
430N/A {
430N/A jboolean useMask= NEXT_BOOLEAN(b);
430N/A jboolean filter = NEXT_BOOLEAN(b);
430N/A jlong pSrc = NEXT_LONG(b);
430N/A jdouble xp0 = NEXT_DOUBLE(b);
430N/A jdouble xp1 = NEXT_DOUBLE(b);
430N/A jdouble xp3 = NEXT_DOUBLE(b);
430N/A jdouble yp0 = NEXT_DOUBLE(b);
430N/A jdouble yp1 = NEXT_DOUBLE(b);
430N/A jdouble yp3 = NEXT_DOUBLE(b);
430N/A res = D3DPaints_SetTexturePaint(d3dc, useMask, pSrc, filter,
430N/A xp0, xp1, xp3,
430N/A yp0, yp1, yp3);
430N/A }
430N/A break;
430N/A
430N/A // BufferedImageOp-related ops
430N/A case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP:
430N/A {
430N/A jlong pSrc = NEXT_LONG(b);
430N/A jboolean edgeZero = NEXT_BOOLEAN(b);
430N/A jint kernelWidth = NEXT_INT(b);
430N/A jint kernelHeight = NEXT_INT(b);
430N/A res = D3DBufImgOps_EnableConvolveOp(d3dc, pSrc, edgeZero,
430N/A kernelWidth, kernelHeight, b);
430N/A SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:
430N/A {
430N/A res = D3DBufImgOps_DisableConvolveOp(d3dc);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:
430N/A {
430N/A jlong pSrc = NEXT_LONG(b); // unused
430N/A jboolean nonPremult = NEXT_BOOLEAN(b);
430N/A jint numFactors = 4;
430N/A unsigned char *scaleFactors = b;
430N/A unsigned char *offsets = (b + numFactors * sizeof(jfloat));
430N/A res = D3DBufImgOps_EnableRescaleOp(d3dc, nonPremult,
430N/A scaleFactors, offsets);
430N/A SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:
430N/A {
430N/A D3DBufImgOps_DisableRescaleOp(d3dc);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:
430N/A {
430N/A jlong pSrc = NEXT_LONG(b); // unused
430N/A jboolean nonPremult = NEXT_BOOLEAN(b);
430N/A jboolean shortData = NEXT_BOOLEAN(b);
430N/A jint numBands = NEXT_INT(b);
430N/A jint bandLength = NEXT_INT(b);
430N/A jint offset = NEXT_INT(b);
430N/A jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte);
430N/A void *tableValues = b;
430N/A res = D3DBufImgOps_EnableLookupOp(d3dc, nonPremult, shortData,
430N/A numBands, bandLength, offset,
430N/A tableValues);
430N/A SKIP_BYTES(b, numBands * bandLength * bytesPerElem);
430N/A }
430N/A break;
430N/A case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:
430N/A {
430N/A res = D3DBufImgOps_DisableLookupOp(d3dc);
430N/A }
430N/A break;
430N/A
430N/A default:
430N/A J2dRlsTraceLn1(J2D_TRACE_ERROR,
430N/A "D3DRQ_flushBuffer: invalid opcode=%d", opcode);
430N/A return;
430N/A }
430N/A // we may mark the surface lost repeatedly but that won't do much harm
430N/A res = D3DRQ_MarkLostIfNeeded(res, dstOps);
430N/A }
430N/A
430N/A if (d3dc != NULL) {
430N/A res = d3dc->EndScene();
430N/A // REMIND: EndScene is not really enough to flush the
430N/A // whole d3d pipeline
430N/A
430N/A // REMIND: there may be an issue with BeginScene/EndScene
430N/A // for each flushQueue, because of the blits, which flush
430N/A // the queue
430N/A if (bSync) {
430N/A res = d3dc->Sync();
430N/A }
430N/A }
430N/A
430N/A // REMIND: we need to also handle hard errors here as well, and disable
430N/A // particular context if needed
430N/A D3DRQ_MarkLostIfNeeded(res, dstOps);
430N/A
430N/A if (!JNU_IsNull(env, pFlush->runnable)) {
430N/A J2dTraceLn(J2D_TRACE_VERBOSE, " executing runnable");
430N/A JNU_CallMethodByName(env, NULL, pFlush->runnable, "run", "()V");
430N/A }
430N/A}
430N/A
430N/A/**
430N/A * Returns a pointer to the "current" context, as set by the last SET_SURFACES
430N/A * or SET_SCRATCH_SURFACE operation.
430N/A */
430N/AD3DContext *
430N/AD3DRQ_GetCurrentContext()
430N/A{
430N/A return d3dc;
430N/A}
430N/A
430N/A/**
430N/A * Returns a pointer to the "current" destination surface, as set by the last
430N/A * SET_SURFACES operation.
430N/A */
430N/AD3DSDOps *
430N/AD3DRQ_GetCurrentDestination()
430N/A{
430N/A return dstOps;
430N/A}
430N/A
430N/A/**
430N/A * Resets current context and destination surface.
430N/A */
430N/Avoid
430N/AD3DRQ_ResetCurrentContextAndDestination()
430N/A{
430N/A J2dTraceLn(J2D_TRACE_INFO, "D3DRQ_ResetCurrentContextAndDestination");
430N/A
430N/A d3dc = NULL;
430N/A dstOps = NULL;
430N/A}
430N/A
430N/Aextern "C"
430N/A{
430N/A
430N/A/*
430N/A * Class: sun_java2d_d3d_D3DRenderQueue
430N/A * Method: flushBuffer
430N/A * Signature: (JILjava/lang/Runnable;)V
430N/A */
430N/AJNIEXPORT void JNICALL
430N/AJava_sun_java2d_d3d_D3DRenderQueue_flushBuffer
430N/A (JNIEnv *env, jobject d3drq, jlong buf, jint limit, jobject runnable)
430N/A{
430N/A FlushBufferStruct bufstr;
430N/A // just in case we forget to init any new fields
430N/A ZeroMemory(&bufstr, sizeof(FlushBufferStruct));
430N/A
430N/A bufstr.buffer = (unsigned char *)jlong_to_ptr(buf);
430N/A if (bufstr.buffer == NULL) {
430N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
430N/A "D3DRenderQueue_flushBuffer: cannot get direct buffer address");
430N/A return;
430N/A }
430N/A bufstr.limit = limit;
430N/A
430N/A bufstr.runnable = JNU_IsNull(env, runnable) ?
430N/A NULL : env->NewGlobalRef(runnable);
430N/A AwtToolkit::GetInstance().InvokeFunction(D3DRQ_FlushBuffer, &bufstr);
430N/A if (!JNU_IsNull(env, bufstr.runnable)) {
430N/A env->DeleteGlobalRef(bufstr.runnable);
430N/A }
430N/A}
430N/A
430N/A}