/* * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #ifndef HEADLESS #include #include #include "sun_java2d_SunGraphics2D.h" #include "MTLPaints.h" #include "MTLVertexCache.h" typedef struct _J2DVertex { jfloat tx, ty; jubyte r, g, b, a; jfloat dx, dy; } J2DVertex; static J2DVertex *vertexCache = NULL; static jint vertexCacheIndex = 0; static jint maskCacheTexID = 0; static jint maskCacheIndex = 0; #define MTLVC_ADD_VERTEX(TX, TY, R, G, B, A, DX, DY) \ do { \ J2DVertex *v = &vertexCache[vertexCacheIndex++]; \ v->tx = TX; \ v->ty = TY; \ v->r = R; \ v->g = G; \ v->b = B; \ v->a = A; \ v->dx = DX; \ v->dy = DY; \ } while (0) #define MTLVC_ADD_QUAD(TX1, TY1, TX2, TY2, DX1, DY1, DX2, DY2, R, G, B, A) \ do { \ MTLVC_ADD_VERTEX(TX1, TY1, R, G, B, A, DX1, DY1); \ MTLVC_ADD_VERTEX(TX2, TY1, R, G, B, A, DX2, DY1); \ MTLVC_ADD_VERTEX(TX2, TY2, R, G, B, A, DX2, DY2); \ MTLVC_ADD_VERTEX(TX1, TY2, R, G, B, A, DX1, DY2); \ } while (0) jboolean MTLVertexCache_InitVertexCache(MTLContext *mtlc) { //TODO J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitVertexCache"); return JNI_TRUE; } void MTLVertexCache_FlushVertexCache() { // TODO J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_FlushVertexCache"); vertexCacheIndex = 0; } /** * This method is somewhat hacky, but necessary for the foreseeable future. * The problem is the way OpenGL handles color values in vertex arrays. When * a vertex in a vertex array contains a color, and then the vertex array * is rendered via glDrawArrays(), the global OpenGL color state is actually * modified each time a vertex is rendered. This means that after all * vertices have been flushed, the global OpenGL color state will be set to * the color of the most recently rendered element in the vertex array. * * The reason this is a problem for us is that we do not want to flush the * vertex array (in the case of mask/glyph operations) or issue a glEnd() * (in the case of non-antialiased primitives) everytime the current color * changes, which would defeat any benefit from batching in the first place. * We handle this in practice by not calling CHECK/RESET_PREVIOUS_OP() when * the simple color state is changing in MTLPaints_SetColor(). This is * problematic for vertex caching because we may end up with the following * situation, for example: * SET_COLOR (orange) * MASK_FILL * MASK_FILL * SET_COLOR (blue; remember, this won't cause a flush) * FILL_RECT (this will cause the vertex array to be flushed) * * In this case, we would actually end up rendering an orange FILL_RECT, * not a blue one as intended, because flushing the vertex cache flush would * override the color state from the most recent SET_COLOR call. * * Long story short, the easiest way to resolve this problem is to call * this method just after disabling the mask/glyph cache, which will ensure * that the appropriate color state is restored. */ void MTLVertexCache_RestoreColorState(MTLContext *mtlc) { // TODO if (mtlc.paintState == sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) { [mtlc setColor:mtlc.pixel]; } } static jboolean MTLVertexCache_InitMaskCache() { // TODO J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitMaskCache"); return JNI_TRUE; } void MTLVertexCache_EnableMaskCache(MTLContext *mtlc) { // TODO J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_EnableMaskCache"); } void MTLVertexCache_DisableMaskCache(MTLContext *mtlc) { // TODO J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_DisableMaskCache"); maskCacheIndex = 0; } void MTLVertexCache_AddMaskQuad(MTLContext *mtlc, jint srcx, jint srcy, jint dstx, jint dsty, jint width, jint height, jint maskscan, void *mask) { // TODO } void MTLVertexCache_AddGlyphQuad(MTLContext *mtlc, jfloat tx1, jfloat ty1, jfloat tx2, jfloat ty2, jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2) { // TODO J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_AddGlyphQuad"); } #endif /* !HEADLESS */