Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/java2d/opengl/OGLRenderQueue.c
38918 views
/*1* Copyright (c) 2005, 2012, 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_SAVE_STATE:505{506j2d_glPushAttrib(GL_ALL_ATTRIB_BITS);507j2d_glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);508j2d_glMatrixMode(GL_MODELVIEW);509j2d_glPushMatrix();510j2d_glMatrixMode(GL_PROJECTION);511j2d_glPushMatrix();512j2d_glMatrixMode(GL_TEXTURE);513j2d_glPushMatrix();514}515break;516517case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE:518{519j2d_glPopAttrib();520j2d_glPopClientAttrib();521j2d_glMatrixMode(GL_MODELVIEW);522j2d_glPopMatrix();523j2d_glMatrixMode(GL_PROJECTION);524j2d_glPopMatrix();525j2d_glMatrixMode(GL_TEXTURE);526j2d_glPopMatrix();527}528break;529case sun_java2d_pipe_BufferedOpCodes_SYNC:530{531sync = JNI_TRUE;532}533break;534535// multibuffering ops536case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS:537{538jlong window = NEXT_LONG(b);539if (oglc != NULL) {540RESET_PREVIOUS_OP();541}542OGLSD_SwapBuffers(env, window);543}544break;545546// special no-op (mainly used for achieving 8-byte alignment)547case sun_java2d_pipe_BufferedOpCodes_NOOP:548break;549550// paint-related ops551case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT:552{553OGLPaints_ResetPaint(oglc);554}555break;556case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:557{558jint pixel = NEXT_INT(b);559OGLPaints_SetColor(oglc, pixel);560}561break;562case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:563{564jboolean useMask= NEXT_BOOLEAN(b);565jboolean cyclic = NEXT_BOOLEAN(b);566jdouble p0 = NEXT_DOUBLE(b);567jdouble p1 = NEXT_DOUBLE(b);568jdouble p3 = NEXT_DOUBLE(b);569jint pixel1 = NEXT_INT(b);570jint pixel2 = NEXT_INT(b);571OGLPaints_SetGradientPaint(oglc, useMask, cyclic,572p0, p1, p3,573pixel1, pixel2);574}575break;576case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:577{578jboolean useMask = NEXT_BOOLEAN(b);579jboolean linear = NEXT_BOOLEAN(b);580jint cycleMethod = NEXT_INT(b);581jint numStops = NEXT_INT(b);582jfloat p0 = NEXT_FLOAT(b);583jfloat p1 = NEXT_FLOAT(b);584jfloat p3 = NEXT_FLOAT(b);585void *fractions, *pixels;586fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));587pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));588OGLPaints_SetLinearGradientPaint(oglc, dstOps,589useMask, linear,590cycleMethod, numStops,591p0, p1, p3,592fractions, pixels);593}594break;595case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:596{597jboolean useMask = NEXT_BOOLEAN(b);598jboolean linear = NEXT_BOOLEAN(b);599jint numStops = NEXT_INT(b);600jint cycleMethod = NEXT_INT(b);601jfloat m00 = NEXT_FLOAT(b);602jfloat m01 = NEXT_FLOAT(b);603jfloat m02 = NEXT_FLOAT(b);604jfloat m10 = NEXT_FLOAT(b);605jfloat m11 = NEXT_FLOAT(b);606jfloat m12 = NEXT_FLOAT(b);607jfloat focusX = NEXT_FLOAT(b);608void *fractions, *pixels;609fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));610pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));611OGLPaints_SetRadialGradientPaint(oglc, dstOps,612useMask, linear,613cycleMethod, numStops,614m00, m01, m02,615m10, m11, m12,616focusX,617fractions, pixels);618}619break;620case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:621{622jboolean useMask= NEXT_BOOLEAN(b);623jboolean filter = NEXT_BOOLEAN(b);624jlong pSrc = NEXT_LONG(b);625jdouble xp0 = NEXT_DOUBLE(b);626jdouble xp1 = NEXT_DOUBLE(b);627jdouble xp3 = NEXT_DOUBLE(b);628jdouble yp0 = NEXT_DOUBLE(b);629jdouble yp1 = NEXT_DOUBLE(b);630jdouble yp3 = NEXT_DOUBLE(b);631OGLPaints_SetTexturePaint(oglc, useMask, pSrc, filter,632xp0, xp1, xp3,633yp0, yp1, yp3);634}635break;636637// BufferedImageOp-related ops638case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP:639{640jlong pSrc = NEXT_LONG(b);641jboolean edgeZero = NEXT_BOOLEAN(b);642jint kernelWidth = NEXT_INT(b);643jint kernelHeight = NEXT_INT(b);644OGLBufImgOps_EnableConvolveOp(oglc, pSrc, edgeZero,645kernelWidth, kernelHeight, b);646SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));647}648break;649case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:650{651OGLBufImgOps_DisableConvolveOp(oglc);652}653break;654case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:655{656jlong pSrc = NEXT_LONG(b);657jboolean nonPremult = NEXT_BOOLEAN(b);658jint numFactors = 4;659unsigned char *scaleFactors = b;660unsigned char *offsets = (b + numFactors * sizeof(jfloat));661OGLBufImgOps_EnableRescaleOp(oglc, pSrc, nonPremult,662scaleFactors, offsets);663SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);664}665break;666case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:667{668OGLBufImgOps_DisableRescaleOp(oglc);669}670break;671case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:672{673jlong pSrc = NEXT_LONG(b);674jboolean nonPremult = NEXT_BOOLEAN(b);675jboolean shortData = NEXT_BOOLEAN(b);676jint numBands = NEXT_INT(b);677jint bandLength = NEXT_INT(b);678jint offset = NEXT_INT(b);679jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte);680void *tableValues = b;681OGLBufImgOps_EnableLookupOp(oglc, pSrc, nonPremult, shortData,682numBands, bandLength, offset,683tableValues);684SKIP_BYTES(b, numBands * bandLength * bytesPerElem);685}686break;687case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:688{689OGLBufImgOps_DisableLookupOp(oglc);690}691break;692693default:694J2dRlsTraceLn1(J2D_TRACE_ERROR,695"OGLRenderQueue_flushBuffer: invalid opcode=%d", opcode);696if (oglc != NULL) {697RESET_PREVIOUS_OP();698}699return;700}701}702703if (oglc != NULL) {704RESET_PREVIOUS_OP();705if (sync) {706j2d_glFinish();707} else {708j2d_glFlush();709}710OGLSD_Flush(env);711}712}713714/**715* Returns a pointer to the "current" context, as set by the last SET_SURFACES716* or SET_SCRATCH_SURFACE operation.717*/718OGLContext *719OGLRenderQueue_GetCurrentContext()720{721return oglc;722}723724/**725* Returns a pointer to the "current" destination surface, as set by the last726* SET_SURFACES operation.727*/728OGLSDOps *729OGLRenderQueue_GetCurrentDestination()730{731return dstOps;732}733734/**735* Used to track whether we are within a series of simple primitive operations736* or texturing operations. The op parameter determines the nature of the737* operation that is to follow. Valid values for this op parameter are:738*739* GL_QUADS740* GL_LINES741* GL_LINE_LOOP742* GL_LINE_STRIP743* (basically any of the valid parameters for glBegin())744*745* GL_TEXTURE_2D746* GL_TEXTURE_RECTANGLE_ARB747*748* OGL_STATE_RESET749* OGL_STATE_CHANGE750* OGL_STATE_MASK_OP751* OGL_STATE_GLYPH_OP752*753* Note that the above constants are guaranteed to be unique values. The754* last few are defined to be negative values to differentiate them from755* the core GL* constants, which are defined to be non-negative.756*757* For simple primitives, this method allows us to batch similar primitives758* within the same glBegin()/glEnd() pair. For example, if we have 100759* consecutive FILL_RECT operations, we only have to call glBegin(GL_QUADS)760* for the first op, and then subsequent operations will consist only of761* glVertex*() calls, which helps improve performance. The glEnd() call762* only needs to be issued before an operation that cannot happen within a763* glBegin()/glEnd() pair (e.g. updating the clip), or one that requires a764* different primitive mode (e.g. GL_LINES).765*766* For operations that involve texturing, this method helps us to avoid767* calling glEnable(GL_TEXTURE_2D) and glDisable(GL_TEXTURE_2D) around each768* operation. For example, if we have an alternating series of ISO_BLIT769* and MASK_BLIT operations (both of which involve texturing), we need770* only to call glEnable(GL_TEXTURE_2D) before the first ISO_BLIT operation.771* The glDisable(GL_TEXTURE_2D) call only needs to be issued before an772* operation that cannot (or should not) happen while texturing is enabled773* (e.g. a context change, or a simple primitive operation like GL_QUADS).774*/775void776OGLRenderQueue_CheckPreviousOp(jint op)777{778if (previousOp == op) {779// The op is the same as last time, so we can return immediately.780return;781}782783J2dTraceLn1(J2D_TRACE_VERBOSE,784"OGLRenderQueue_CheckPreviousOp: new op=%d", op);785786switch (previousOp) {787case GL_TEXTURE_2D:788case GL_TEXTURE_RECTANGLE_ARB:789if (op == OGL_STATE_CHANGE) {790// Optimization: Certain state changes (those marked as791// OGL_STATE_CHANGE) are allowed while texturing is enabled.792// In this case, we can allow previousOp to remain as it is and793// then return early.794return;795} else {796// Otherwise, op must be a primitive operation, or a reset, so797// we will disable texturing.798j2d_glDisable(previousOp);799// This next step of binding to zero should not be strictly800// necessary, but on some older Nvidia boards (e.g. GeForce 2)801// problems will arise if GL_TEXTURE_2D and802// GL_TEXTURE_RECTANGLE_ARB are bound at the same time, so we803// will do this just to be safe.804j2d_glBindTexture(previousOp, 0);805}806break;807case OGL_STATE_MASK_OP:808OGLVertexCache_DisableMaskCache(oglc);809break;810case OGL_STATE_GLYPH_OP:811OGLTR_DisableGlyphVertexCache(oglc);812break;813case OGL_STATE_PGRAM_OP:814OGLRenderer_DisableAAParallelogramProgram();815break;816case OGL_STATE_RESET:817case OGL_STATE_CHANGE:818// No-op819break;820default:821// In this case, op must be one of:822// - the start of a different primitive type (glBegin())823// - a texturing operation824// - a state change (not allowed within glBegin()/glEnd() pairs)825// - a reset826// so we must first complete the previous primitive operation.827j2d_glEnd();828break;829}830831switch (op) {832case GL_TEXTURE_2D:833case GL_TEXTURE_RECTANGLE_ARB:834// We are starting a texturing operation, so enable texturing.835j2d_glEnable(op);836break;837case OGL_STATE_MASK_OP:838OGLVertexCache_EnableMaskCache(oglc);839break;840case OGL_STATE_GLYPH_OP:841OGLTR_EnableGlyphVertexCache(oglc);842break;843case OGL_STATE_PGRAM_OP:844OGLRenderer_EnableAAParallelogramProgram();845break;846case OGL_STATE_RESET:847case OGL_STATE_CHANGE:848// No-op849break;850default:851// We are starting a primitive operation, so call glBegin() with852// the given primitive type.853j2d_glBegin(op);854break;855}856857previousOp = op;858}859860#endif /* !HEADLESS */861862863