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 */