1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #ifndef HEADLESS 27 28 #include <stdlib.h> 29 #include <string.h> 30 31 #include "sun_java2d_SunGraphics2D.h" 32 33 #include "MTLPaints.h" 34 #include "MTLVertexCache.h" 35 36 typedef struct _J2DVertex { 37 jfloat tx, ty; 38 jubyte r, g, b, a; 39 jfloat dx, dy; 40 } J2DVertex; 41 42 static J2DVertex *vertexCache = NULL; 43 static jint vertexCacheIndex = 0; 44 45 static jint maskCacheTexID = 0; 46 static jint maskCacheIndex = 0; 47 48 #define MTLVC_ADD_VERTEX(TX, TY, R, G, B, A, DX, DY) \ 49 do { \ 50 J2DVertex *v = &vertexCache[vertexCacheIndex++]; \ 51 v->tx = TX; \ 52 v->ty = TY; \ 53 v->r = R; \ 54 v->g = G; \ 55 v->b = B; \ 56 v->a = A; \ 57 v->dx = DX; \ 58 v->dy = DY; \ 59 } while (0) 60 61 #define MTLVC_ADD_QUAD(TX1, TY1, TX2, TY2, DX1, DY1, DX2, DY2, R, G, B, A) \ 62 do { \ 63 MTLVC_ADD_VERTEX(TX1, TY1, R, G, B, A, DX1, DY1); \ 64 MTLVC_ADD_VERTEX(TX2, TY1, R, G, B, A, DX2, DY1); \ 65 MTLVC_ADD_VERTEX(TX2, TY2, R, G, B, A, DX2, DY2); \ 66 MTLVC_ADD_VERTEX(TX1, TY2, R, G, B, A, DX1, DY2); \ 67 } while (0) 68 69 jboolean 70 MTLVertexCache_InitVertexCache(MTLContext *mtlc) 71 { 72 //TODO 73 J2dTraceNotImplPrimitive("MTLVertexCache_InitVertexCache"); 74 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitVertexCache"); 75 return JNI_TRUE; 76 } 77 78 void 79 MTLVertexCache_FlushVertexCache() 80 { 81 // TODO 82 J2dTraceNotImplPrimitive("MTLVertexCache_FlushVertexCache"); 83 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_FlushVertexCache"); 84 vertexCacheIndex = 0; 85 } 86 87 /** 88 * This method is somewhat hacky, but necessary for the foreseeable future. 89 * The problem is the way OpenGL handles color values in vertex arrays. When 90 * a vertex in a vertex array contains a color, and then the vertex array 91 * is rendered via glDrawArrays(), the global OpenGL color state is actually 92 * modified each time a vertex is rendered. This means that after all 93 * vertices have been flushed, the global OpenGL color state will be set to 94 * the color of the most recently rendered element in the vertex array. 95 * 96 * The reason this is a problem for us is that we do not want to flush the 97 * vertex array (in the case of mask/glyph operations) or issue a glEnd() 98 * (in the case of non-antialiased primitives) everytime the current color 99 * changes, which would defeat any benefit from batching in the first place. 100 * We handle this in practice by not calling CHECK/RESET_PREVIOUS_OP() when 101 * the simple color state is changing in MTLPaints_SetColor(). This is 102 * problematic for vertex caching because we may end up with the following 103 * situation, for example: 104 * SET_COLOR (orange) 105 * MASK_FILL 106 * MASK_FILL 107 * SET_COLOR (blue; remember, this won't cause a flush) 108 * FILL_RECT (this will cause the vertex array to be flushed) 109 * 110 * In this case, we would actually end up rendering an orange FILL_RECT, 111 * not a blue one as intended, because flushing the vertex cache flush would 112 * override the color state from the most recent SET_COLOR call. 113 * 114 * Long story short, the easiest way to resolve this problem is to call 115 * this method just after disabling the mask/glyph cache, which will ensure 116 * that the appropriate color state is restored. 117 */ 118 void 119 MTLVertexCache_RestoreColorState(MTLContext *mtlc) 120 { 121 // TODO 122 J2dTraceNotImplPrimitive("MTLVertexCache_RestoreColorState"); 123 if (mtlc.paintState == sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) { 124 [mtlc setColor:mtlc.pixel]; 125 } 126 } 127 128 static jboolean 129 MTLVertexCache_InitMaskCache() 130 { 131 // TODO 132 J2dTraceNotImplPrimitive("MTLVertexCache_InitMaskCache"); 133 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitMaskCache"); 134 return JNI_TRUE; 135 } 136 137 void 138 MTLVertexCache_EnableMaskCache(MTLContext *mtlc) 139 { 140 // TODO 141 J2dTraceNotImplPrimitive("MTLVertexCache_EnableMaskCache"); 142 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_EnableMaskCache"); 143 } 144 145 void 146 MTLVertexCache_DisableMaskCache(MTLContext *mtlc) 147 { 148 // TODO 149 J2dTraceNotImplPrimitive("MTLVertexCache_DisableMaskCache"); 150 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_DisableMaskCache"); 151 maskCacheIndex = 0; 152 } 153 154 void 155 MTLVertexCache_AddMaskQuad(MTLContext *mtlc, 156 jint srcx, jint srcy, 157 jint dstx, jint dsty, 158 jint width, jint height, 159 jint maskscan, void *mask) 160 { 161 // TODO 162 J2dTraceNotImplPrimitive("MTLVertexCache_AddMaskQuad"); 163 } 164 165 void 166 MTLVertexCache_AddGlyphQuad(MTLContext *mtlc, 167 jfloat tx1, jfloat ty1, jfloat tx2, jfloat ty2, 168 jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2) 169 { 170 // TODO 171 J2dTraceNotImplPrimitive("MTLVertexCache_AddGlyphQuad"); 172 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_AddGlyphQuad"); 173 } 174 175 #endif /* !HEADLESS */