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 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitVertexCache"); 74 return JNI_TRUE; 75 } 76 77 void 78 MTLVertexCache_FlushVertexCache() 79 { 80 // TODO 81 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_FlushVertexCache"); 82 vertexCacheIndex = 0; 83 } 84 85 /** 86 * This method is somewhat hacky, but necessary for the foreseeable future. 87 * The problem is the way OpenGL handles color values in vertex arrays. When 88 * a vertex in a vertex array contains a color, and then the vertex array 89 * is rendered via glDrawArrays(), the global OpenGL color state is actually 90 * modified each time a vertex is rendered. This means that after all 91 * vertices have been flushed, the global OpenGL color state will be set to 92 * the color of the most recently rendered element in the vertex array. 93 * 94 * The reason this is a problem for us is that we do not want to flush the 95 * vertex array (in the case of mask/glyph operations) or issue a glEnd() 96 * (in the case of non-antialiased primitives) everytime the current color 97 * changes, which would defeat any benefit from batching in the first place. 98 * We handle this in practice by not calling CHECK/RESET_PREVIOUS_OP() when 99 * the simple color state is changing in MTLPaints_SetColor(). This is 100 * problematic for vertex caching because we may end up with the following 101 * situation, for example: 102 * SET_COLOR (orange) 103 * MASK_FILL 104 * MASK_FILL 105 * SET_COLOR (blue; remember, this won't cause a flush) 106 * FILL_RECT (this will cause the vertex array to be flushed) 107 * 108 * In this case, we would actually end up rendering an orange FILL_RECT, 109 * not a blue one as intended, because flushing the vertex cache flush would 110 * override the color state from the most recent SET_COLOR call. 111 * 112 * Long story short, the easiest way to resolve this problem is to call 113 * this method just after disabling the mask/glyph cache, which will ensure 114 * that the appropriate color state is restored. 115 */ 116 void 117 MTLVertexCache_RestoreColorState(MTLContext *mtlc) 118 { 119 // TODO 120 if (mtlc.paintState == sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) { 121 [mtlc setColor:mtlc.pixel]; 122 } 123 } 124 125 static jboolean 126 MTLVertexCache_InitMaskCache() 127 { 128 // TODO 129 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitMaskCache"); 130 return JNI_TRUE; 131 } 132 133 void 134 MTLVertexCache_EnableMaskCache(MTLContext *mtlc) 135 { 136 // TODO 137 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_EnableMaskCache"); 138 } 139 140 void 141 MTLVertexCache_DisableMaskCache(MTLContext *mtlc) 142 { 143 // TODO 144 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_DisableMaskCache"); 145 maskCacheIndex = 0; 146 } 147 148 void 149 MTLVertexCache_AddMaskQuad(MTLContext *mtlc, 150 jint srcx, jint srcy, 151 jint dstx, jint dsty, 152 jint width, jint height, 153 jint maskscan, void *mask) 154 { 155 // TODO 156 } 157 158 void 159 MTLVertexCache_AddGlyphQuad(MTLContext *mtlc, 160 jfloat tx1, jfloat ty1, jfloat tx2, jfloat ty2, 161 jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2) 162 { 163 // TODO 164 J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_AddGlyphQuad"); 165 } 166 167 #endif /* !HEADLESS */