Path: blob/master/src/java.desktop/share/native/common/java2d/opengl/OGLRenderQueue.c
41159 views
/*1* Copyright (c) 2005, 2019, 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#ifndef HEADLESS2627#include <stdlib.h>2829#include "sun_java2d_pipe_BufferedOpCodes.h"3031#include "jlong.h"32#include "OGLBlitLoops.h"33#include "OGLBufImgOps.h"34#include "OGLContext.h"35#include "OGLMaskBlit.h"36#include "OGLMaskFill.h"37#include "OGLPaints.h"38#include "OGLRenderQueue.h"39#include "OGLRenderer.h"40#include "OGLSurfaceData.h"41#include "OGLTextRenderer.h"42#include "OGLVertexCache.h"4344/**45* Used to track whether we are in a series of a simple primitive operations46* or texturing operations. This variable should be controlled only via47* the INIT/CHECK/RESET_PREVIOUS_OP() macros. See the48* OGLRenderQueue_CheckPreviousOp() method below for more information.49*/50jint previousOp;5152/**53* References to the "current" context and destination surface.54*/55static OGLContext *oglc = NULL;56static OGLSDOps *dstOps = NULL;5758/**59* The following methods are implemented in the windowing system (i.e. GLX60* and WGL) source files.61*/62extern OGLContext *OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo);63extern void OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo);64extern void OGLSD_SwapBuffers(JNIEnv *env, jlong window);65extern void OGLSD_Flush(JNIEnv *env);6667JNIEXPORT void JNICALL68Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer69(JNIEnv *env, jobject oglrq,70jlong buf, jint limit)71{72jboolean sync = JNI_FALSE;73unsigned char *b, *end;7475J2dTraceLn1(J2D_TRACE_INFO,76"OGLRenderQueue_flushBuffer: limit=%d", limit);7778b = (unsigned char *)jlong_to_ptr(buf);79if (b == NULL) {80J2dRlsTraceLn(J2D_TRACE_ERROR,81"OGLRenderQueue_flushBuffer: cannot get direct buffer address");82return;83}8485INIT_PREVIOUS_OP();86end = b + limit;8788while (b < end) {89jint opcode = NEXT_INT(b);9091J2dTraceLn2(J2D_TRACE_VERBOSE,92"OGLRenderQueue_flushBuffer: opcode=%d, rem=%d",93opcode, (end-b));9495switch (opcode) {9697// draw ops98case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:99{100jint x1 = NEXT_INT(b);101jint y1 = NEXT_INT(b);102jint x2 = NEXT_INT(b);103jint y2 = NEXT_INT(b);104OGLRenderer_DrawLine(oglc, x1, y1, x2, y2);105}106break;107case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:108{109jint x = NEXT_INT(b);110jint y = NEXT_INT(b);111jint w = NEXT_INT(b);112jint h = NEXT_INT(b);113OGLRenderer_DrawRect(oglc, x, y, w, h);114}115break;116case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY:117{118jint nPoints = NEXT_INT(b);119jboolean isClosed = NEXT_BOOLEAN(b);120jint transX = NEXT_INT(b);121jint transY = NEXT_INT(b);122jint *xPoints = (jint *)b;123jint *yPoints = ((jint *)b) + nPoints;124OGLRenderer_DrawPoly(oglc, nPoints, isClosed,125transX, transY,126xPoints, yPoints);127SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT);128}129break;130case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL:131{132jint x = NEXT_INT(b);133jint y = NEXT_INT(b);134// Note that we could use GL_POINTS here, but the common135// use case for DRAW_PIXEL is when rendering a Path2D,136// which will consist of a mix of DRAW_PIXEL and DRAW_LINE137// calls. So to improve batching we use GL_LINES here,138// even though it requires an extra vertex per pixel.139CONTINUE_IF_NULL(oglc);140CHECK_PREVIOUS_OP(GL_LINES);141j2d_glVertex2i(x, y);142j2d_glVertex2i(x+1, y+1);143}144break;145case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:146{147jint count = NEXT_INT(b);148OGLRenderer_DrawScanlines(oglc, count, (jint *)b);149SKIP_BYTES(b, count * BYTES_PER_SCANLINE);150}151break;152case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:153{154jfloat x11 = NEXT_FLOAT(b);155jfloat y11 = NEXT_FLOAT(b);156jfloat dx21 = NEXT_FLOAT(b);157jfloat dy21 = NEXT_FLOAT(b);158jfloat dx12 = NEXT_FLOAT(b);159jfloat dy12 = NEXT_FLOAT(b);160jfloat lwr21 = NEXT_FLOAT(b);161jfloat lwr12 = NEXT_FLOAT(b);162OGLRenderer_DrawParallelogram(oglc,163x11, y11,164dx21, dy21,165dx12, dy12,166lwr21, lwr12);167}168break;169case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM:170{171jfloat x11 = NEXT_FLOAT(b);172jfloat y11 = NEXT_FLOAT(b);173jfloat dx21 = NEXT_FLOAT(b);174jfloat dy21 = NEXT_FLOAT(b);175jfloat dx12 = NEXT_FLOAT(b);176jfloat dy12 = NEXT_FLOAT(b);177jfloat lwr21 = NEXT_FLOAT(b);178jfloat lwr12 = NEXT_FLOAT(b);179OGLRenderer_DrawAAParallelogram(oglc, dstOps,180x11, y11,181dx21, dy21,182dx12, dy12,183lwr21, lwr12);184}185break;186187// fill ops188case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:189{190jint x = NEXT_INT(b);191jint y = NEXT_INT(b);192jint w = NEXT_INT(b);193jint h = NEXT_INT(b);194OGLRenderer_FillRect(oglc, x, y, w, h);195}196break;197case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:198{199jint count = NEXT_INT(b);200OGLRenderer_FillSpans(oglc, count, (jint *)b);201SKIP_BYTES(b, count * BYTES_PER_SPAN);202}203break;204case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:205{206jfloat x11 = NEXT_FLOAT(b);207jfloat y11 = NEXT_FLOAT(b);208jfloat dx21 = NEXT_FLOAT(b);209jfloat dy21 = NEXT_FLOAT(b);210jfloat dx12 = NEXT_FLOAT(b);211jfloat dy12 = NEXT_FLOAT(b);212OGLRenderer_FillParallelogram(oglc,213x11, y11,214dx21, dy21,215dx12, dy12);216}217break;218case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:219{220jfloat x11 = NEXT_FLOAT(b);221jfloat y11 = NEXT_FLOAT(b);222jfloat dx21 = NEXT_FLOAT(b);223jfloat dy21 = NEXT_FLOAT(b);224jfloat dx12 = NEXT_FLOAT(b);225jfloat dy12 = NEXT_FLOAT(b);226OGLRenderer_FillAAParallelogram(oglc, dstOps,227x11, y11,228dx21, dy21,229dx12, dy12);230}231break;232233// text-related ops234case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST:235{236jint numGlyphs = NEXT_INT(b);237jint packedParams = NEXT_INT(b);238jfloat glyphListOrigX = NEXT_FLOAT(b);239jfloat glyphListOrigY = NEXT_FLOAT(b);240jboolean usePositions = EXTRACT_BOOLEAN(packedParams,241OFFSET_POSITIONS);242jboolean subPixPos = EXTRACT_BOOLEAN(packedParams,243OFFSET_SUBPIXPOS);244jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams,245OFFSET_RGBORDER);246jint lcdContrast = EXTRACT_BYTE(packedParams,247OFFSET_CONTRAST);248unsigned char *images = b;249unsigned char *positions;250jint bytesPerGlyph;251if (usePositions) {252positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE);253bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH;254} else {255positions = NULL;256bytesPerGlyph = BYTES_PER_GLYPH_IMAGE;257}258OGLTR_DrawGlyphList(env, oglc, dstOps,259numGlyphs, usePositions,260subPixPos, rgbOrder, lcdContrast,261glyphListOrigX, glyphListOrigY,262images, positions);263SKIP_BYTES(b, numGlyphs * bytesPerGlyph);264}265break;266267// copy-related ops268case sun_java2d_pipe_BufferedOpCodes_COPY_AREA:269{270jint x = NEXT_INT(b);271jint y = NEXT_INT(b);272jint w = NEXT_INT(b);273jint h = NEXT_INT(b);274jint dx = NEXT_INT(b);275jint dy = NEXT_INT(b);276OGLBlitLoops_CopyArea(env, oglc, dstOps,277x, y, w, h, dx, dy);278}279break;280case sun_java2d_pipe_BufferedOpCodes_BLIT:281{282jint packedParams = NEXT_INT(b);283jint sx1 = NEXT_INT(b);284jint sy1 = NEXT_INT(b);285jint sx2 = NEXT_INT(b);286jint sy2 = NEXT_INT(b);287jdouble dx1 = NEXT_DOUBLE(b);288jdouble dy1 = NEXT_DOUBLE(b);289jdouble dx2 = NEXT_DOUBLE(b);290jdouble dy2 = NEXT_DOUBLE(b);291jlong pSrc = NEXT_LONG(b);292jlong pDst = NEXT_LONG(b);293jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT);294jboolean texture = EXTRACT_BOOLEAN(packedParams,295OFFSET_TEXTURE);296jboolean rtt = EXTRACT_BOOLEAN(packedParams,297OFFSET_RTT);298jboolean xform = EXTRACT_BOOLEAN(packedParams,299OFFSET_XFORM);300jboolean isoblit = EXTRACT_BOOLEAN(packedParams,301OFFSET_ISOBLIT);302if (isoblit) {303OGLBlitLoops_IsoBlit(env, oglc, pSrc, pDst,304xform, hint, texture, rtt,305sx1, sy1, sx2, sy2,306dx1, dy1, dx2, dy2);307} else {308jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE);309OGLBlitLoops_Blit(env, oglc, pSrc, pDst,310xform, hint, srctype, texture,311sx1, sy1, sx2, sy2,312dx1, dy1, dx2, dy2);313}314}315break;316case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT:317{318jint sx = NEXT_INT(b);319jint sy = NEXT_INT(b);320jint dx = NEXT_INT(b);321jint dy = NEXT_INT(b);322jint w = NEXT_INT(b);323jint h = NEXT_INT(b);324jint dsttype = NEXT_INT(b);325jlong pSrc = NEXT_LONG(b);326jlong pDst = NEXT_LONG(b);327OGLBlitLoops_SurfaceToSwBlit(env, oglc,328pSrc, pDst, dsttype,329sx, sy, dx, dy, w, h);330}331break;332case sun_java2d_pipe_BufferedOpCodes_MASK_FILL:333{334jint x = NEXT_INT(b);335jint y = NEXT_INT(b);336jint w = NEXT_INT(b);337jint h = NEXT_INT(b);338jint maskoff = NEXT_INT(b);339jint maskscan = NEXT_INT(b);340jint masklen = NEXT_INT(b);341unsigned char *pMask = (masklen > 0) ? b : NULL;342OGLMaskFill_MaskFill(oglc, x, y, w, h,343maskoff, maskscan, masklen, pMask);344SKIP_BYTES(b, masklen);345}346break;347case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT:348{349jint dstx = NEXT_INT(b);350jint dsty = NEXT_INT(b);351jint width = NEXT_INT(b);352jint height = NEXT_INT(b);353jint masklen = width * height * sizeof(jint);354OGLMaskBlit_MaskBlit(env, oglc,355dstx, dsty, width, height, b);356SKIP_BYTES(b, masklen);357}358break;359360// state-related ops361case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP:362{363jint x1 = NEXT_INT(b);364jint y1 = NEXT_INT(b);365jint x2 = NEXT_INT(b);366jint y2 = NEXT_INT(b);367OGLContext_SetRectClip(oglc, dstOps, x1, y1, x2, y2);368}369break;370case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:371{372OGLContext_BeginShapeClip(oglc);373}374break;375case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:376{377jint count = NEXT_INT(b);378OGLRenderer_FillSpans(oglc, count, (jint *)b);379SKIP_BYTES(b, count * BYTES_PER_SPAN);380}381break;382case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:383{384OGLContext_EndShapeClip(oglc, dstOps);385}386break;387case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:388{389OGLContext_ResetClip(oglc);390}391break;392case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:393{394jint rule = NEXT_INT(b);395jfloat extraAlpha = NEXT_FLOAT(b);396jint flags = NEXT_INT(b);397OGLContext_SetAlphaComposite(oglc, rule, extraAlpha, flags);398}399break;400case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:401{402jint xorPixel = NEXT_INT(b);403OGLContext_SetXorComposite(oglc, xorPixel);404}405break;406case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:407{408OGLContext_ResetComposite(oglc);409}410break;411case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:412{413jdouble m00 = NEXT_DOUBLE(b);414jdouble m10 = NEXT_DOUBLE(b);415jdouble m01 = NEXT_DOUBLE(b);416jdouble m11 = NEXT_DOUBLE(b);417jdouble m02 = NEXT_DOUBLE(b);418jdouble m12 = NEXT_DOUBLE(b);419OGLContext_SetTransform(oglc, m00, m10, m01, m11, m02, m12);420}421break;422case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:423{424OGLContext_ResetTransform(oglc);425}426break;427428// context-related ops429case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:430{431jlong pSrc = NEXT_LONG(b);432jlong pDst = NEXT_LONG(b);433if (oglc != NULL) {434RESET_PREVIOUS_OP();435}436oglc = OGLContext_SetSurfaces(env, pSrc, pDst);437dstOps = (OGLSDOps *)jlong_to_ptr(pDst);438}439break;440case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:441{442jlong pConfigInfo = NEXT_LONG(b);443if (oglc != NULL) {444RESET_PREVIOUS_OP();445}446oglc = OGLSD_SetScratchSurface(env, pConfigInfo);447dstOps = NULL;448}449break;450case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:451{452jlong pData = NEXT_LONG(b);453OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);454if (oglsdo != NULL) {455CONTINUE_IF_NULL(oglc);456RESET_PREVIOUS_OP();457OGLSD_Delete(env, oglsdo);458}459}460break;461case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:462{463jlong pData = NEXT_LONG(b);464OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);465if (oglsdo != NULL) {466CONTINUE_IF_NULL(oglc);467RESET_PREVIOUS_OP();468OGLSD_Delete(env, oglsdo);469if (oglsdo->privOps != NULL) {470free(oglsdo->privOps);471}472}473}474break;475case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:476{477jlong pConfigInfo = NEXT_LONG(b);478CONTINUE_IF_NULL(oglc);479RESET_PREVIOUS_OP();480OGLGC_DestroyOGLGraphicsConfig(pConfigInfo);481482// the previous method will call glX/wglMakeCurrent(None),483// so we should nullify the current oglc and dstOps to avoid484// calling glFlush() (or similar) while no context is current485oglc = NULL;486dstOps = NULL;487}488break;489case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:490{491// flush just in case there are any pending operations in492// the hardware pipe493if (oglc != NULL) {494RESET_PREVIOUS_OP();495j2d_glFlush();496}497498// invalidate the references to the current context and499// destination surface that are maintained at the native level500oglc = NULL;501dstOps = NULL;502}503break;504case sun_java2d_pipe_BufferedOpCodes_SYNC:505{506sync = JNI_TRUE;507}508break;509510// multibuffering ops511case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS:512{513jlong window = NEXT_LONG(b);514if (oglc != NULL) {515RESET_PREVIOUS_OP();516}517OGLSD_SwapBuffers(env, window);518}519break;520521// special no-op (mainly used for achieving 8-byte alignment)522case sun_java2d_pipe_BufferedOpCodes_NOOP:523break;524525// paint-related ops526case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT:527{528OGLPaints_ResetPaint(oglc);529}530break;531case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:532{533jint pixel = NEXT_INT(b);534OGLPaints_SetColor(oglc, pixel);535}536break;537case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:538{539jboolean useMask= NEXT_BOOLEAN(b);540jboolean cyclic = NEXT_BOOLEAN(b);541jdouble p0 = NEXT_DOUBLE(b);542jdouble p1 = NEXT_DOUBLE(b);543jdouble p3 = NEXT_DOUBLE(b);544jint pixel1 = NEXT_INT(b);545jint pixel2 = NEXT_INT(b);546OGLPaints_SetGradientPaint(oglc, useMask, cyclic,547p0, p1, p3,548pixel1, pixel2);549}550break;551case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:552{553jboolean useMask = NEXT_BOOLEAN(b);554jboolean linear = NEXT_BOOLEAN(b);555jint cycleMethod = NEXT_INT(b);556jint numStops = NEXT_INT(b);557jfloat p0 = NEXT_FLOAT(b);558jfloat p1 = NEXT_FLOAT(b);559jfloat p3 = NEXT_FLOAT(b);560void *fractions, *pixels;561fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));562pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));563OGLPaints_SetLinearGradientPaint(oglc, dstOps,564useMask, linear,565cycleMethod, numStops,566p0, p1, p3,567fractions, pixels);568}569break;570case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:571{572jboolean useMask = NEXT_BOOLEAN(b);573jboolean linear = NEXT_BOOLEAN(b);574jint numStops = NEXT_INT(b);575jint cycleMethod = NEXT_INT(b);576jfloat m00 = NEXT_FLOAT(b);577jfloat m01 = NEXT_FLOAT(b);578jfloat m02 = NEXT_FLOAT(b);579jfloat m10 = NEXT_FLOAT(b);580jfloat m11 = NEXT_FLOAT(b);581jfloat m12 = NEXT_FLOAT(b);582jfloat focusX = NEXT_FLOAT(b);583void *fractions, *pixels;584fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));585pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));586OGLPaints_SetRadialGradientPaint(oglc, dstOps,587useMask, linear,588cycleMethod, numStops,589m00, m01, m02,590m10, m11, m12,591focusX,592fractions, pixels);593}594break;595case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:596{597jboolean useMask= NEXT_BOOLEAN(b);598jboolean filter = NEXT_BOOLEAN(b);599jlong pSrc = NEXT_LONG(b);600jdouble xp0 = NEXT_DOUBLE(b);601jdouble xp1 = NEXT_DOUBLE(b);602jdouble xp3 = NEXT_DOUBLE(b);603jdouble yp0 = NEXT_DOUBLE(b);604jdouble yp1 = NEXT_DOUBLE(b);605jdouble yp3 = NEXT_DOUBLE(b);606OGLPaints_SetTexturePaint(oglc, useMask, pSrc, filter,607xp0, xp1, xp3,608yp0, yp1, yp3);609}610break;611612// BufferedImageOp-related ops613case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP:614{615jlong pSrc = NEXT_LONG(b);616jboolean edgeZero = NEXT_BOOLEAN(b);617jint kernelWidth = NEXT_INT(b);618jint kernelHeight = NEXT_INT(b);619OGLBufImgOps_EnableConvolveOp(oglc, pSrc, edgeZero,620kernelWidth, kernelHeight, b);621SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));622}623break;624case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:625{626OGLBufImgOps_DisableConvolveOp(oglc);627}628break;629case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:630{631jlong pSrc = NEXT_LONG(b);632jboolean nonPremult = NEXT_BOOLEAN(b);633jint numFactors = 4;634unsigned char *scaleFactors = b;635unsigned char *offsets = (b + numFactors * sizeof(jfloat));636OGLBufImgOps_EnableRescaleOp(oglc, pSrc, nonPremult,637scaleFactors, offsets);638SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);639}640break;641case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:642{643OGLBufImgOps_DisableRescaleOp(oglc);644}645break;646case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:647{648jlong pSrc = NEXT_LONG(b);649jboolean nonPremult = NEXT_BOOLEAN(b);650jboolean shortData = NEXT_BOOLEAN(b);651jint numBands = NEXT_INT(b);652jint bandLength = NEXT_INT(b);653jint offset = NEXT_INT(b);654jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte);655void *tableValues = b;656OGLBufImgOps_EnableLookupOp(oglc, pSrc, nonPremult, shortData,657numBands, bandLength, offset,658tableValues);659SKIP_BYTES(b, numBands * bandLength * bytesPerElem);660}661break;662case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:663{664OGLBufImgOps_DisableLookupOp(oglc);665}666break;667668default:669J2dRlsTraceLn1(J2D_TRACE_ERROR,670"OGLRenderQueue_flushBuffer: invalid opcode=%d", opcode);671if (oglc != NULL) {672RESET_PREVIOUS_OP();673}674return;675}676}677678if (oglc != NULL) {679RESET_PREVIOUS_OP();680if (sync) {681j2d_glFinish();682} else {683j2d_glFlush();684}685OGLSD_Flush(env);686}687}688689/**690* Returns a pointer to the "current" context, as set by the last SET_SURFACES691* or SET_SCRATCH_SURFACE operation.692*/693OGLContext *694OGLRenderQueue_GetCurrentContext()695{696return oglc;697}698699/**700* Returns a pointer to the "current" destination surface, as set by the last701* SET_SURFACES operation.702*/703OGLSDOps *704OGLRenderQueue_GetCurrentDestination()705{706return dstOps;707}708709/**710* Used to track whether we are within a series of simple primitive operations711* or texturing operations. The op parameter determines the nature of the712* operation that is to follow. Valid values for this op parameter are:713*714* GL_QUADS715* GL_LINES716* GL_LINE_LOOP717* GL_LINE_STRIP718* (basically any of the valid parameters for glBegin())719*720* GL_TEXTURE_2D721* GL_TEXTURE_RECTANGLE_ARB722*723* OGL_STATE_RESET724* OGL_STATE_CHANGE725* OGL_STATE_MASK_OP726* OGL_STATE_GLYPH_OP727*728* Note that the above constants are guaranteed to be unique values. The729* last few are defined to be negative values to differentiate them from730* the core GL* constants, which are defined to be non-negative.731*732* For simple primitives, this method allows us to batch similar primitives733* within the same glBegin()/glEnd() pair. For example, if we have 100734* consecutive FILL_RECT operations, we only have to call glBegin(GL_QUADS)735* for the first op, and then subsequent operations will consist only of736* glVertex*() calls, which helps improve performance. The glEnd() call737* only needs to be issued before an operation that cannot happen within a738* glBegin()/glEnd() pair (e.g. updating the clip), or one that requires a739* different primitive mode (e.g. GL_LINES).740*741* For operations that involve texturing, this method helps us to avoid742* calling glEnable(GL_TEXTURE_2D) and glDisable(GL_TEXTURE_2D) around each743* operation. For example, if we have an alternating series of ISO_BLIT744* and MASK_BLIT operations (both of which involve texturing), we need745* only to call glEnable(GL_TEXTURE_2D) before the first ISO_BLIT operation.746* The glDisable(GL_TEXTURE_2D) call only needs to be issued before an747* operation that cannot (or should not) happen while texturing is enabled748* (e.g. a context change, or a simple primitive operation like GL_QUADS).749*/750void751OGLRenderQueue_CheckPreviousOp(jint op)752{753if (previousOp == op) {754// The op is the same as last time, so we can return immediately.755return;756}757758J2dTraceLn1(J2D_TRACE_VERBOSE,759"OGLRenderQueue_CheckPreviousOp: new op=%d", op);760761switch (previousOp) {762case GL_TEXTURE_2D:763case GL_TEXTURE_RECTANGLE_ARB:764if (op == OGL_STATE_CHANGE) {765// Optimization: Certain state changes (those marked as766// OGL_STATE_CHANGE) are allowed while texturing is enabled.767// In this case, we can allow previousOp to remain as it is and768// then return early.769return;770} else {771// Otherwise, op must be a primitive operation, or a reset, so772// we will disable texturing.773j2d_glDisable(previousOp);774// This next step of binding to zero should not be strictly775// necessary, but on some older Nvidia boards (e.g. GeForce 2)776// problems will arise if GL_TEXTURE_2D and777// GL_TEXTURE_RECTANGLE_ARB are bound at the same time, so we778// will do this just to be safe.779j2d_glBindTexture(previousOp, 0);780}781break;782case OGL_STATE_MASK_OP:783OGLVertexCache_DisableMaskCache(oglc);784break;785case OGL_STATE_GLYPH_OP:786OGLTR_DisableGlyphVertexCache(oglc);787break;788case OGL_STATE_PGRAM_OP:789OGLRenderer_DisableAAParallelogramProgram();790break;791case OGL_STATE_RESET:792case OGL_STATE_CHANGE:793// No-op794break;795default:796// In this case, op must be one of:797// - the start of a different primitive type (glBegin())798// - a texturing operation799// - a state change (not allowed within glBegin()/glEnd() pairs)800// - a reset801// so we must first complete the previous primitive operation.802j2d_glEnd();803break;804}805806switch (op) {807case GL_TEXTURE_2D:808case GL_TEXTURE_RECTANGLE_ARB:809// We are starting a texturing operation, so enable texturing.810j2d_glEnable(op);811break;812case OGL_STATE_MASK_OP:813OGLVertexCache_EnableMaskCache(oglc);814break;815case OGL_STATE_GLYPH_OP:816OGLTR_EnableGlyphVertexCache(oglc);817break;818case OGL_STATE_PGRAM_OP:819OGLRenderer_EnableAAParallelogramProgram();820break;821case OGL_STATE_RESET:822case OGL_STATE_CHANGE:823// No-op824break;825default:826// We are starting a primitive operation, so call glBegin() with827// the given primitive type.828j2d_glBegin(op);829break;830}831832previousOp = op;833}834835#endif /* !HEADLESS */836837838