src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m
branchmetal-prototype-branch
changeset 57416 e153174dba06
child 57426 68ec5c5ae381
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m	Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,167 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+#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 */