From 10cce382bffd5210c8ec00809e64aee30f83d7cd Mon Sep 17 00:00:00 2001 From: Oliver Behnke <oliver.behnke@aei.mpg.de> Date: Fri, 22 Nov 2024 14:28:32 +0100 Subject: [PATCH] Removed Metal backend * See: https://gitlab.aei.uni-hannover.de/einsteinathome/jdk-macos-legacy * <jdk-macos-legacy>/patches/17/remove_metal_backend.sh <jdk17u> --- .../java2d/metal/EncoderManager.h | 101 -- .../java2d/metal/EncoderManager.m | 471 --------- .../libawt_lwawt/java2d/metal/MTLBlitLoops.h | 78 -- .../libawt_lwawt/java2d/metal/MTLBlitLoops.m | 860 --------------- .../libawt_lwawt/java2d/metal/MTLBufImgOps.h | 74 -- .../libawt_lwawt/java2d/metal/MTLBufImgOps.m | 223 ---- .../libawt_lwawt/java2d/metal/MTLClip.h | 88 -- .../libawt_lwawt/java2d/metal/MTLClip.m | 318 ------ .../libawt_lwawt/java2d/metal/MTLComposite.h | 64 -- .../libawt_lwawt/java2d/metal/MTLComposite.m | 192 ---- .../libawt_lwawt/java2d/metal/MTLContext.h | 244 ----- .../libawt_lwawt/java2d/metal/MTLContext.m | 492 --------- .../libawt_lwawt/java2d/metal/MTLGlyphCache.h | 99 -- .../libawt_lwawt/java2d/metal/MTLGlyphCache.m | 364 ------- .../java2d/metal/MTLGraphicsConfig.h | 50 - .../java2d/metal/MTLGraphicsConfig.m | 154 --- .../libawt_lwawt/java2d/metal/MTLLayer.h | 75 -- .../libawt_lwawt/java2d/metal/MTLLayer.m | 290 ----- .../libawt_lwawt/java2d/metal/MTLMaskBlit.h | 36 - .../libawt_lwawt/java2d/metal/MTLMaskBlit.m | 70 -- .../libawt_lwawt/java2d/metal/MTLMaskFill.h | 36 - .../libawt_lwawt/java2d/metal/MTLMaskFill.m | 114 -- .../libawt_lwawt/java2d/metal/MTLPaints.h | 142 --- .../libawt_lwawt/java2d/metal/MTLPaints.m | 993 ------------------ .../java2d/metal/MTLPipelineStatesStorage.h | 77 -- .../java2d/metal/MTLPipelineStatesStorage.m | 326 ------ .../java2d/metal/MTLRenderQueue.h | 106 -- .../java2d/metal/MTLRenderQueue.m | 933 ---------------- .../libawt_lwawt/java2d/metal/MTLRenderer.h | 76 -- .../libawt_lwawt/java2d/metal/MTLRenderer.m | 961 ----------------- .../java2d/metal/MTLSamplerManager.h | 45 - .../java2d/metal/MTLSamplerManager.m | 90 -- .../java2d/metal/MTLStencilManager.h | 43 - .../java2d/metal/MTLStencilManager.m | 72 -- .../java2d/metal/MTLSurfaceData.h | 48 - .../java2d/metal/MTLSurfaceData.m | 355 ------- .../java2d/metal/MTLSurfaceDataBase.h | 128 --- .../java2d/metal/MTLTextRenderer.h | 59 -- .../java2d/metal/MTLTextRenderer.m | 845 --------------- .../java2d/metal/MTLTexturePool.h | 74 -- .../libawt_lwawt/java2d/metal/MTLTexurePool.m | 455 -------- .../libawt_lwawt/java2d/metal/MTLTransform.h | 48 - .../libawt_lwawt/java2d/metal/MTLTransform.m | 99 -- .../libawt_lwawt/java2d/metal/MTLUtils.h | 33 - .../libawt_lwawt/java2d/metal/MTLUtils.m | 84 -- .../java2d/metal/MTLVertexCache.h | 86 -- .../java2d/metal/MTLVertexCache.m | 326 ------ .../libawt_lwawt/java2d/metal/RenderOptions.h | 45 - .../native/libawt_lwawt/java2d/metal/common.h | 164 --- .../libawt_lwawt/java2d/metal/shaders.metal | 807 -------------- 50 files changed, 12013 deletions(-) delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceDataBase.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexturePool.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h delete mode 100644 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders.metal diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h deleted file mode 100644 index bec085f93db..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 EncoderManager_h_Included -#define EncoderManager_h_Included - -#import <Metal/Metal.h> - -#include "RenderOptions.h" - -@class MTLContex; - -/** - * The EncoderManager class used to obtain MTLRenderCommandEncoder (or MTLBlitCommandEncoder) corresponding - * to the current state of MTLContext. - * - * Due to performance issues (creation of MTLRenderCommandEncoder isn't cheap), each getXXXEncoder invocation - * updates properties of common (cached) encoder and returns this encoder. - * - * Base method getEncoder does the following: - * 1. Checks whether common encoder must be closed and recreated (some of encoder properties is 'persistent', - * for example destination, stencil, or any other property of MTLRenderPassDescriptor) - * 2. Updates 'mutable' properties encoder: pipelineState (with corresponding buffers), clip, transform, e.t.c. To avoid - * unnecessary calls of [encoder setXXX] this manager compares requested state with cached one. - */ -@interface EncoderManager : NSObject -- (id _Nonnull)init; -- (void)dealloc; - -- (void)setContext:(MTLContex * _Nonnull)mtlc; - -// returns encoder that renders/fills geometry with current paint and composite -- (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps; - -- (id<MTLRenderCommandEncoder> _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps; - -- (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(id<MTLTexture> _Nonnull)dest - isDstOpaque:(bool)isOpaque; - -- (id<MTLRenderCommandEncoder> _Nonnull)getAAShaderRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps; - -// returns encoder that renders/fills geometry with current composite and with given texture -// (user must call [encoder setFragmentTexture] before any rendering) -- (id<MTLRenderCommandEncoder> _Nonnull)getTextureEncoder:(const BMTLSDOps * _Nonnull)dstOps - isSrcOpaque:(bool)isSrcOpaque; - -- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque; - -- (id<MTLRenderCommandEncoder> _Nonnull) getLCDEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque; - -- (id<MTLRenderCommandEncoder> _Nonnull)getTextureEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque - interpolation:(int)interpolation; - -- (id<MTLRenderCommandEncoder> _Nonnull)getTextureEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque - interpolation:(int)interpolation - isAA:(jboolean)isAA; - -- (id<MTLRenderCommandEncoder> _Nonnull)getTextEncoder:(const BMTLSDOps * _Nonnull)dstOps - isSrcOpaque:(bool)isSrcOpaque; - -// Base method to obtain any MTLRenderCommandEncoder -- (id<MTLRenderCommandEncoder> _Nonnull) getEncoder:(id<MTLTexture> _Nonnull)dest - isDestOpaque:(jboolean)isDestOpaque - renderOptions:(const RenderOptions * _Nonnull)renderOptions; - -- (id<MTLBlitCommandEncoder> _Nonnull)createBlitEncoder; - -- (void)endEncoder; -@end - -#endif // EncoderManager_h_Included diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m deleted file mode 100644 index 0fb18c3f4c3..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "EncoderManager.h" -#include "MTLContext.h" -#include "sun_java2d_SunGraphics2D.h" -#import "common.h" - -// NOTE: uncomment to disable comparing cached encoder states with requested (for debugging) -// #define ALWAYS_UPDATE_ENCODER_STATES - -const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; - -// Internal utility class that represents the set of 'mutable' encoder properties -@interface EncoderStates : NSObject -@property (readonly) MTLClip * clip; - -- (id)init; -- (void)dealloc; - -- (void)reset:(id<MTLTexture>)destination - isDstOpaque:(jboolean)isDstOpaque - isDstPremultiplied:(jboolean)isDstPremultiplied - isAA:(jboolean)isAA - isText:(jboolean)isText - isLCD:(jboolean)isLCD; - -- (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - forceUpdate:(jboolean)forceUpdate; -@property (assign) jboolean aa; -@property (assign) jboolean text; -@property (assign) jboolean lcd; -@property (assign) jboolean aaShader; -@property (retain) MTLPaint* paint; -@end - -@implementation EncoderStates { - MTLPipelineStatesStorage * _pipelineStateStorage; - id<MTLDevice> _device; - - // Persistent encoder properties - id<MTLTexture> _destination; - SurfaceRasterFlags _dstFlags; - - jboolean _isAA; - jboolean _isText; - jboolean _isLCD; - jboolean _isAAShader; - - // - // Cached 'mutable' states of encoder - // - - // Composite rule and source raster flags (it affects the CAD-multipliers (of pipelineState)) - MTLComposite * _composite; - SurfaceRasterFlags _srcFlags; - - // Paint mode (it affects shaders (of pipelineState) and corresponding buffers) - MTLPaint * _paint; - - // If true, indicates that encoder is used for texture drawing (user must do [encoder setFragmentTexture:] before drawing) - jboolean _isTexture; - int _interpolationMode; - - // Clip rect or stencil - MTLClip * _clip; - - // Transform (affects transformation inside vertex shader) - MTLTransform * _transform; -} -@synthesize aa = _isAA; -@synthesize text = _isText; -@synthesize lcd = _isLCD; -@synthesize aaShader = _isAAShader; -@synthesize paint = _paint; - -- (id)init { - self = [super init]; - if (self) { - _destination = nil; - _composite = [[MTLComposite alloc] init]; - _paint = [[MTLPaint alloc] init]; - _transform = [[MTLTransform alloc] init]; - _clip = [[MTLClip alloc] init]; - } - return self; -} - -- (void)dealloc { - [_composite release]; - [_paint release]; - [_transform release]; - [super dealloc]; -} - -- (void)setContext:(MTLContext * _Nonnull)mtlc { - self->_pipelineStateStorage = mtlc.pipelineStateStorage; - self->_device = mtlc.device; -} - -- (void)reset:(id<MTLTexture>)destination - isDstOpaque:(jboolean)isDstOpaque - isDstPremultiplied:(jboolean)isDstPremultiplied - isAA:(jboolean)isAA - isText:(jboolean)isText - isLCD:(jboolean)isLCD { - _destination = destination; - _dstFlags.isOpaque = isDstOpaque; - _dstFlags.isPremultiplied = isDstPremultiplied; - _isAA = isAA; - _isText = isText; - _isLCD = isLCD; - // NOTE: probably it's better to invalidate/reset all cached states now -} - -- (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - forceUpdate:(jboolean)forceUpdate -{ - // 1. Process special case for stencil mask generation - if (mtlc.clip.stencilMaskGenerationInProgress == JNI_TRUE) { - // use separate pipeline state for stencil generation - if (forceUpdate || (_clip.stencilMaskGenerationInProgress != JNI_TRUE)) { - [_clip copyFrom:mtlc.clip]; - [_clip setMaskGenerationPipelineState:encoder - destWidth:_destination.width - destHeight:_destination.height - pipelineStateStorage:_pipelineStateStorage]; - } - - [self updateTransform:encoder transform:mtlc.transform forceUpdate:forceUpdate]; - return; - } - - // 2. Otherwise update all 'mutable' properties of encoder - [self updatePipelineState:encoder - context:mtlc - renderOptions:renderOptions - forceUpdate:forceUpdate]; - [self updateTransform:encoder transform:mtlc.transform forceUpdate:forceUpdate]; - [self updateClip:encoder clip:mtlc.clip forceUpdate:forceUpdate]; -} - -// -// Internal methods that update states when necessary (compare with cached states) -// - -// Updates pipelineState (and corresponding buffers) with use of paint+composite+flags -- (void)updatePipelineState:(id<MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - forceUpdate:(jboolean)forceUpdate -{ - if (!forceUpdate - && [_paint isEqual:mtlc.paint] - && [_composite isEqual:mtlc.composite] - && (_isTexture == renderOptions->isTexture && (!renderOptions->isTexture || _interpolationMode == renderOptions->interpolation)) // interpolation is used only in texture mode - && _isAA == renderOptions->isAA - && _isAAShader == renderOptions->isAAShader - && _isText == renderOptions->isText - && _isLCD == renderOptions->isLCD - && _srcFlags.isOpaque == renderOptions->srcFlags.isOpaque && _srcFlags.isPremultiplied == renderOptions->srcFlags.isPremultiplied) - return; - - self.paint = mtlc.paint; - [_composite copyFrom:mtlc.composite]; - _isTexture = renderOptions->isTexture; - _interpolationMode = renderOptions->interpolation; - _isAA = renderOptions->isAA; - _isAAShader = renderOptions->isAAShader; - _isText = renderOptions->isText; - _isLCD = renderOptions->isLCD; - _srcFlags = renderOptions->srcFlags; - - if ((jint)[mtlc.composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR) { - - [mtlc.paint setXorModePipelineState:encoder - context:mtlc - renderOptions:renderOptions - pipelineStateStorage:_pipelineStateStorage]; - } else { - [mtlc.paint setPipelineState:encoder - context:mtlc - renderOptions:renderOptions - pipelineStateStorage:_pipelineStateStorage]; - } -} - -- (void) updateClip:(id<MTLRenderCommandEncoder>)encoder clip:(MTLClip *)clip forceUpdate:(jboolean)forceUpdate -{ - if (clip.stencilMaskGenerationInProgress == JNI_TRUE) { - // don't set setScissorOrStencil when generation in progress - return; - } - - if (!forceUpdate && [_clip isEqual:clip]) - return; - - [_clip copyFrom:clip]; - [_clip setScissorOrStencil:encoder - destWidth:_destination.width - destHeight:_destination.height - device:_device]; -} - -- (void)updateTransform:(id <MTLRenderCommandEncoder>)encoder - transform:(MTLTransform *)transform - forceUpdate:(jboolean)forceUpdate -{ - if (!forceUpdate - && [_transform isEqual:transform]) - return; - - [_transform copyFrom:transform]; - [_transform setVertexMatrix:encoder - destWidth:_destination.width - destHeight:_destination.height]; -} - -@end - -@implementation EncoderManager { - MTLContext * _mtlc; // used to obtain CommandBufferWrapper and Composite/Paint/Transform - - id<MTLRenderCommandEncoder> _encoder; - - // 'Persistent' properties of encoder - id<MTLTexture> _destination; - id<MTLTexture> _aaDestination; - BOOL _useStencil; - - // 'Mutable' states of encoder - EncoderStates * _encoderStates; -} - -- (id _Nonnull)init { - self = [super init]; - if (self) { - _encoder = nil; - _destination = nil; - _aaDestination = nil; - _useStencil = NO; - _encoderStates = [[EncoderStates alloc] init]; - - } - return self; -} - -- (void)dealloc { - [_encoderStates release]; - [super dealloc]; -} - -- (void)setContext:(MTLContex * _Nonnull)mtlc { - self->_mtlc = mtlc; - [self->_encoderStates setContext:mtlc]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps -{ - return [self getRenderEncoder:dstOps->pTexture isDstOpaque:dstOps->isOpaque]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps { - id<MTLTexture> dstTxt = dstOps->pTexture; - RenderOptions roptions = {JNI_FALSE, JNI_TRUE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {dstOps->isOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; - return [self getEncoder:dstTxt renderOptions:&roptions]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull)getAAShaderRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps -{ - RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {dstOps->isOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_TRUE}; - return [self getEncoder:dstOps->pTexture renderOptions:&roptions]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(id<MTLTexture> _Nonnull)dest - isDstOpaque:(bool)isOpaque -{ - RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {isOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; - return [self getEncoder:dest renderOptions:&roptions]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(const BMTLSDOps * _Nonnull)dstOps - isSrcOpaque:(bool)isSrcOpaque -{ - return [self getTextureEncoder:dstOps->pTexture - isSrcOpaque:isSrcOpaque - isDstOpaque:dstOps->isOpaque - interpolation:INTERPOLATION_NEAREST_NEIGHBOR]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque -{ - return [self getTextureEncoder:dest - isSrcOpaque:isSrcOpaque - isDstOpaque:isDstOpaque - interpolation:INTERPOLATION_NEAREST_NEIGHBOR - isAA:JNI_FALSE]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getLCDEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque -{ - RenderOptions roptions = {JNI_TRUE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, {isSrcOpaque, JNI_TRUE }, {isDstOpaque, JNI_TRUE}, JNI_FALSE, JNI_TRUE, JNI_FALSE}; - return [self getEncoder:dest renderOptions:&roptions]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque - interpolation:(int)interpolation - isAA:(jboolean)isAA -{ - RenderOptions roptions = {JNI_TRUE, isAA, interpolation, { isSrcOpaque, JNI_TRUE }, {isDstOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; - return [self getEncoder:dest renderOptions:&roptions]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest - isSrcOpaque:(bool)isSrcOpaque - isDstOpaque:(bool)isDstOpaque - interpolation:(int)interpolation -{ - return [self getTextureEncoder:dest isSrcOpaque:isSrcOpaque isDstOpaque:isDstOpaque interpolation:interpolation isAA:JNI_FALSE]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getTextEncoder:(const BMTLSDOps * _Nonnull)dstOps - isSrcOpaque:(bool)isSrcOpaque -{ - RenderOptions roptions = {JNI_TRUE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, { isSrcOpaque, JNI_TRUE }, {dstOps->isOpaque, JNI_TRUE}, JNI_TRUE, JNI_FALSE, JNI_FALSE}; - return [self getEncoder:dstOps->pTexture renderOptions:&roptions]; -} - -- (id<MTLRenderCommandEncoder> _Nonnull) getEncoder:(id <MTLTexture> _Nonnull)dest - renderOptions:(const RenderOptions * _Nonnull)renderOptions -{ - // - // 1. check whether it's necessary to call endEncoder - // - jboolean needEnd = JNI_FALSE; - if (_encoder != nil) { - if (_destination != dest || renderOptions->isAA != _encoderStates.aa) { - J2dTraceLn2(J2D_TRACE_VERBOSE, - "end common encoder because of dest change: %p -> %p", - _destination, dest); - needEnd = JNI_TRUE; - } else if ((_useStencil == NO) != ([_mtlc.clip isShape] == NO)) { - // 1. When mode changes RECT -> SHAPE we must recreate encoder with - // stencilAttachment (todo: consider the case when current encoder already - // has stencil) - // - // 2. When mode changes SHAPE -> RECT it seems that we can use the same - // encoder with disabled stencil test, but [encoder - // setDepthStencilState:nil] causes crash, so we have to recreate encoder - // in such case - J2dTraceLn2(J2D_TRACE_VERBOSE, - "end common encoder because toggle stencil: %d -> %d", - (int)_useStencil, (int)[_mtlc.clip isShape]); - needEnd = JNI_TRUE; - } - } - if (needEnd) - [self endEncoder]; - - // - // 2. recreate encoder if necessary - // - jboolean forceUpdate = JNI_FALSE; -#ifdef ALWAYS_UPDATE_ENCODER_STATES - forceUpdate = JNI_TRUE; -#endif // ALWAYS_UPDATE_ENCODER_STATES - - if (_encoder == nil) { - _destination = dest; - _useStencil = [_mtlc.clip isShape] && !_mtlc.clip.stencilMaskGenerationInProgress; - forceUpdate = JNI_TRUE; - - MTLCommandBufferWrapper *cbw = [_mtlc getCommandBufferWrapper]; - MTLRenderPassDescriptor *rpd = - [MTLRenderPassDescriptor renderPassDescriptor]; - MTLRenderPassColorAttachmentDescriptor *ca = rpd.colorAttachments[0]; - ca.texture = dest; - - // TODO: Find out why we cannot use - // if (_mtlc.clip.stencilMaskGenerationInProgress == YES) { - // ca.loadAction = MTLLoadActionClear; - // ca.clearColor = MTLClearColorMake(0.0f, 0.0f,0.0f, 0.0f); - // } - // here to avoid creation of clearEncoder in beginShapeClip - - ca.loadAction = MTLLoadActionLoad; - ca.storeAction = MTLStoreActionStore; - - if (_useStencil && !renderOptions->isAA) { - // If you enable stencil testing or stencil writing, the - // MTLRenderPassDescriptor must include a stencil attachment. - rpd.stencilAttachment.loadAction = MTLLoadActionLoad; - rpd.stencilAttachment.storeAction = MTLStoreActionStore; - rpd.stencilAttachment.texture = _mtlc.clip.stencilTextureRef; - } else if (_mtlc.clip.stencilMaskGenerationInProgress == YES) { - rpd.stencilAttachment.texture = _mtlc.clip.dstOps->pStencilTexture; - rpd.stencilAttachment.clearStencil = 0; - rpd.stencilAttachment.loadAction = _mtlc.clip.stencilMaskGenerationStarted? MTLLoadActionLoad : MTLLoadActionClear; - _mtlc.clip.stencilMaskGenerationStarted = YES; - rpd.stencilAttachment.storeAction = MTLStoreActionStore; - } - - // J2dTraceLn1(J2D_TRACE_VERBOSE, "created render encoder to draw on - // tex=%p", dest); - _encoder = [[cbw getCommandBuffer] renderCommandEncoderWithDescriptor:rpd]; - - [_encoderStates reset:dest - isDstOpaque:renderOptions->dstFlags.isOpaque - isDstPremultiplied:YES - isAA:renderOptions->isAA - isText:renderOptions->isText - isLCD:renderOptions->isLCD]; - } - - // - // 3. update encoder states - // - [_encoderStates updateEncoder:_encoder - context:_mtlc - renderOptions:renderOptions - forceUpdate:forceUpdate]; - - return _encoder; -} - -- (id<MTLBlitCommandEncoder> _Nonnull) createBlitEncoder { - [self endEncoder]; - return [[[_mtlc getCommandBufferWrapper] getCommandBuffer] blitCommandEncoder]; -} - -- (void) endEncoder { - if (_encoder != nil) { - [_encoder endEncoding]; - _encoder = nil; - _destination = nil; - } -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.h deleted file mode 100644 index 839615a044c..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLBlitLoops_h_Included -#define MTLBlitLoops_h_Included - -#include "sun_java2d_metal_MTLBlitLoops.h" -#include "MTLSurfaceDataBase.h" -#include "MTLContext.h" - -#define OFFSET_SRCTYPE sun_java2d_metal_MTLBlitLoops_OFFSET_SRCTYPE -#define OFFSET_HINT sun_java2d_metal_MTLBlitLoops_OFFSET_HINT -#define OFFSET_TEXTURE sun_java2d_metal_MTLBlitLoops_OFFSET_TEXTURE -#define OFFSET_RTT sun_java2d_metal_MTLBlitLoops_OFFSET_RTT -#define OFFSET_XFORM sun_java2d_metal_MTLBlitLoops_OFFSET_XFORM -#define OFFSET_ISOBLIT sun_java2d_metal_MTLBlitLoops_OFFSET_ISOBLIT - -void MTLBlitLoops_IsoBlit(JNIEnv *env, - MTLContext *mtlc, jlong pSrcOps, jlong pDstOps, - jboolean xform, jint hint, - jboolean texture, - jint sx1, jint sy1, - jint sx2, jint sy2, - jdouble dx1, jdouble dy1, - jdouble dx2, jdouble dy2); - -void MTLBlitLoops_Blit(JNIEnv *env, - MTLContext *mtlc, jlong pSrcOps, jlong pDstOps, - jboolean xform, jint hint, - jint srctype, jboolean texture, - jint sx1, jint sy1, - jint sx2, jint sy2, - jdouble dx1, jdouble dy1, - jdouble dx2, jdouble dy2); - -void MTLBlitLoops_SurfaceToSwBlit(JNIEnv *env, MTLContext *mtlc, - jlong pSrcOps, jlong pDstOps, jint dsttype, - jint srcx, jint srcy, - jint dstx, jint dsty, - jint width, jint height); - -void MTLBlitLoops_CopyArea(JNIEnv *env, - MTLContext *mtlc, BMTLSDOps *dstOps, - jint x, jint y, - jint width, jint height, - jint dx, jint dy); - -void MTLBlitTex2Tex(MTLContext *mtlc, id<MTLTexture> src, id<MTLTexture> dest); - -void drawTex2Tex(MTLContext *mtlc, - id<MTLTexture> src, id<MTLTexture> dst, - jboolean isSrcOpaque, jboolean isDstOpaque, jint hint, - jint sx1, jint sy1, jint sx2, jint sy2, - jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2); - -#endif /* MTLBlitLoops_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m deleted file mode 100644 index bf55d8c8976..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m +++ /dev/null @@ -1,860 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <jni.h> -#include <jlong.h> - -#include "SurfaceData.h" -#include "MTLBlitLoops.h" -#include "MTLRenderQueue.h" -#include "MTLSurfaceData.h" -#include "MTLUtils.h" -#include "GraphicsPrimitiveMgr.h" - -#include <string.h> // memcpy -#include "IntArgbPre.h" - -#import <Accelerate/Accelerate.h> - -#ifdef DEBUG -#define TRACE_ISOBLIT -#define TRACE_BLIT -#endif //DEBUG -//#define DEBUG_ISOBLIT -//#define DEBUG_BLIT - -typedef struct { - // Consider deleting this field, since it's always MTLPixelFormatBGRA8Unorm - jboolean hasAlpha; - jboolean isPremult; - const uint8_t* swizzleMap; -} MTLRasterFormatInfo; - - -const uint8_t rgb_to_rgba[4] = {0, 1, 2, 3}; -const uint8_t xrgb_to_rgba[4] = {1, 2, 3, 0}; -const uint8_t bgr_to_rgba[4] = {2, 1, 0, 3}; -const uint8_t xbgr_to_rgba[4] = {3, 2, 1, 0}; - -/** - * This table contains the "pixel formats" for all system memory surfaces - * that Metal is capable of handling, indexed by the "PF_" constants defined - * in MTLLSurfaceData.java. These pixel formats contain information that is - * passed to Metal when copying from a system memory ("Sw") surface to - * an Metal surface - */ -MTLRasterFormatInfo RasterFormatInfos[] = { - { 1, 0, nil }, /* 0 - IntArgb */ // Argb (in java notation) - { 1, 1, nil }, /* 1 - IntArgbPre */ - { 0, 1, rgb_to_rgba }, /* 2 - IntRgb */ - { 0, 1, xrgb_to_rgba }, /* 3 - IntRgbx */ - { 0, 1, bgr_to_rgba }, /* 4 - IntBgr */ - { 0, 1, xbgr_to_rgba }, /* 5 - IntBgrx */ - -// TODO: support 2-byte formats -// { GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, -// 2, 0, 1, }, /* 7 - Ushort555Rgb */ -// { GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, -// 2, 0, 1, }, /* 8 - Ushort555Rgbx*/ -// { GL_LUMINANCE, GL_UNSIGNED_BYTE, -// 1, 0, 1, }, /* 9 - ByteGray */ -// { GL_LUMINANCE, GL_UNSIGNED_SHORT, -// 2, 0, 1, }, /*10 - UshortGray */ -// { GL_BGR, GL_UNSIGNED_BYTE, -// 1, 0, 1, }, /*11 - ThreeByteBgr */ -}; - -extern void J2dTraceImpl(int level, jboolean cr, const char *string, ...); - -void fillTxQuad( - struct TxtVertex * txQuadVerts, - jint sx1, jint sy1, jint sx2, jint sy2, jint sw, jint sh, - jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dw, jdouble dh -) { - const float nsx1 = sx1/(float)sw; - const float nsy1 = sy1/(float)sh; - const float nsx2 = sx2/(float)sw; - const float nsy2 = sy2/(float)sh; - - txQuadVerts[0].position[0] = dx1; - txQuadVerts[0].position[1] = dy1; - txQuadVerts[0].txtpos[0] = nsx1; - txQuadVerts[0].txtpos[1] = nsy1; - - txQuadVerts[1].position[0] = dx2; - txQuadVerts[1].position[1] = dy1; - txQuadVerts[1].txtpos[0] = nsx2; - txQuadVerts[1].txtpos[1] = nsy1; - - txQuadVerts[2].position[0] = dx2; - txQuadVerts[2].position[1] = dy2; - txQuadVerts[2].txtpos[0] = nsx2; - txQuadVerts[2].txtpos[1] = nsy2; - - txQuadVerts[3].position[0] = dx2; - txQuadVerts[3].position[1] = dy2; - txQuadVerts[3].txtpos[0] = nsx2; - txQuadVerts[3].txtpos[1] = nsy2; - - txQuadVerts[4].position[0] = dx1; - txQuadVerts[4].position[1] = dy2; - txQuadVerts[4].txtpos[0] = nsx1; - txQuadVerts[4].txtpos[1] = nsy2; - - txQuadVerts[5].position[0] = dx1; - txQuadVerts[5].position[1] = dy1; - txQuadVerts[5].txtpos[0] = nsx1; - txQuadVerts[5].txtpos[1] = nsy1; -} - -//#define TRACE_drawTex2Tex - -void drawTex2Tex(MTLContext *mtlc, - id<MTLTexture> src, id<MTLTexture> dst, - jboolean isSrcOpaque, jboolean isDstOpaque, jint hint, - jint sx1, jint sy1, jint sx2, jint sy2, - jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2) -{ -#ifdef TRACE_drawTex2Tex - J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "drawTex2Tex: src tex=%p, dst tex=%p", src, dst); - J2dRlsTraceLn4(J2D_TRACE_VERBOSE, " sw=%d sh=%d dw=%d dh=%d", src.width, src.height, dst.width, dst.height); - J2dRlsTraceLn4(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d", sx1, sy1, sx2, sy2); - J2dRlsTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f", dx1, dy1, dx2, dy2); -#endif //TRACE_drawTex2Tex - - id<MTLRenderCommandEncoder> encoder = [mtlc.encoderManager getTextureEncoder:dst - isSrcOpaque:isSrcOpaque - isDstOpaque:isDstOpaque - interpolation:hint - ]; - - struct TxtVertex quadTxVerticesBuffer[6]; - fillTxQuad(quadTxVerticesBuffer, sx1, sy1, sx2, sy2, src.width, src.height, dx1, dy1, dx2, dy2, dst.width, dst.height); - - [encoder setVertexBytes:quadTxVerticesBuffer length:sizeof(quadTxVerticesBuffer) atIndex:MeshVertexBuffer]; - [encoder setFragmentTexture:src atIndex: 0]; - [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; -} - -static void fillSwizzleUniforms(struct SwizzleUniforms *uniforms, const MTLRasterFormatInfo *rfi) { - const size_t SWIZZLE_MAP_SIZE = 4; - memcpy(&uniforms->swizzle, rfi->swizzleMap, SWIZZLE_MAP_SIZE); - uniforms->hasAlpha = rfi->hasAlpha; -} - -static void -replaceTextureRegion(MTLContext *mtlc, id<MTLTexture> dest, const SurfaceDataRasInfo *srcInfo, - const MTLRasterFormatInfo *rfi, - int dx1, int dy1, int dx2, int dy2) { - const int sw = MIN(srcInfo->bounds.x2 - srcInfo->bounds.x1, MTL_GPU_FAMILY_MAC_TXT_SIZE); - const int sh = MIN(srcInfo->bounds.y2 - srcInfo->bounds.y1, MTL_GPU_FAMILY_MAC_TXT_SIZE); - const int dw = MIN(dx2 - dx1, MTL_GPU_FAMILY_MAC_TXT_SIZE); - const int dh = MIN(dy2 - dy1, MTL_GPU_FAMILY_MAC_TXT_SIZE); - - if (dw < sw || dh < sh) { - J2dTraceLn4(J2D_TRACE_ERROR, "replaceTextureRegion: dest size: (%d, %d) less than source size: (%d, %d)", dw, dh, sw, sh); - return; - } - - const void *raster = srcInfo->rasBase; - raster += (NSUInteger)srcInfo->bounds.y1 * (NSUInteger)srcInfo->scanStride + (NSUInteger)srcInfo->bounds.x1 * (NSUInteger)srcInfo->pixelStride; - - @autoreleasepool { - J2dTraceLn4(J2D_TRACE_VERBOSE, "replaceTextureRegion src (dw, dh) : [%d, %d] dest (dx1, dy1) =[%d, %d]", - dw, dh, dx1, dy1); - id<MTLBuffer> buff = [[mtlc.device newBufferWithLength:(sw * sh * srcInfo->pixelStride) options:MTLResourceStorageModeManaged] autorelease]; - - // copy src pixels inside src bounds to buff - for (int row = 0; row < sh; row++) { - memcpy(buff.contents + (row * sw * srcInfo->pixelStride), raster, sw * srcInfo->pixelStride); - raster += (NSUInteger)srcInfo->scanStride; - } - [buff didModifyRange:NSMakeRange(0, buff.length)]; - - if (rfi->swizzleMap != nil) { - id <MTLBuffer> swizzled = [[mtlc.device newBufferWithLength:(sw * sh * srcInfo->pixelStride) options:MTLResourceStorageModeManaged] autorelease]; - - // this should be cheap, since data is already on GPU - id<MTLCommandBuffer> cb = [mtlc createCommandBuffer]; - id<MTLComputeCommandEncoder> computeEncoder = [cb computeCommandEncoder]; - id<MTLComputePipelineState> computePipelineState = [mtlc.pipelineStateStorage - getComputePipelineState:@"swizzle_to_rgba"]; - [computeEncoder setComputePipelineState:computePipelineState]; - - [computeEncoder setBuffer:buff offset:0 atIndex:0]; - [computeEncoder setBuffer:swizzled offset:0 atIndex:1]; - - struct SwizzleUniforms uniforms; - fillSwizzleUniforms(&uniforms, rfi); - [computeEncoder setBytes:&uniforms length:sizeof(struct SwizzleUniforms) atIndex:2]; - - NSUInteger pixelCount = buff.length / srcInfo->pixelStride; - [computeEncoder setBytes:&pixelCount length:sizeof(NSUInteger) atIndex:3]; - - NSUInteger threadGroupSize = computePipelineState.maxTotalThreadsPerThreadgroup; - if (threadGroupSize == 0) { - threadGroupSize = 1; - } - MTLSize threadsPerGroup = MTLSizeMake(threadGroupSize, 1, 1); - MTLSize threadGroups = MTLSizeMake((pixelCount + threadGroupSize - 1) / threadGroupSize, - 1, 1); - [computeEncoder dispatchThreadgroups:threadGroups - threadsPerThreadgroup:threadsPerGroup]; - [computeEncoder endEncoding]; - [cb commit]; - - buff = swizzled; - } - - id<MTLBlitCommandEncoder> blitEncoder = [mtlc.encoderManager createBlitEncoder]; - [blitEncoder copyFromBuffer:buff - sourceOffset:0 sourceBytesPerRow:(sw * srcInfo->pixelStride) - sourceBytesPerImage:(sw * sh * srcInfo->pixelStride) sourceSize:MTLSizeMake(sw, sh, 1) - toTexture:dest - destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(dx1, dy1, 0)]; - [blitEncoder endEncoding]; - [mtlc.encoderManager endEncoder]; - - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - } -} - -/** - * Inner loop used for copying a source system memory ("Sw") surface to a - * destination MTL "Surface". This method is invoked from - * MTLBlitLoops_Blit(). - */ - -static void -MTLBlitSwToTextureViaPooledTexture( - MTLContext *mtlc, SurfaceDataRasInfo *srcInfo, BMTLSDOps * bmtlsdOps, - MTLRasterFormatInfo *rfi, jint hint, - jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2) -{ - int sw = srcInfo->bounds.x2 - srcInfo->bounds.x1; - int sh = srcInfo->bounds.y2 - srcInfo->bounds.y1; - - sw = MIN(sw, MTL_GPU_FAMILY_MAC_TXT_SIZE); - sh = MIN(sh, MTL_GPU_FAMILY_MAC_TXT_SIZE); - - id<MTLTexture> dest = bmtlsdOps->pTexture; - - MTLPooledTextureHandle * texHandle = [mtlc.texturePool getTexture:sw height:sh format:MTLPixelFormatBGRA8Unorm]; - if (texHandle == nil) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitSwToTextureViaPooledTexture: can't obtain temporary texture object from pool"); - return; - } - [[mtlc getCommandBufferWrapper] registerPooledTexture:texHandle]; - - id<MTLTexture> texBuff = texHandle.texture; - replaceTextureRegion(mtlc, texBuff, srcInfo, rfi, 0, 0, sw, sh); - - drawTex2Tex(mtlc, texBuff, dest, !rfi->hasAlpha, bmtlsdOps->isOpaque, hint, - 0, 0, sw, sh, dx1, dy1, dx2, dy2); -} - -static -jboolean isIntegerAndUnscaled( - jint sx1, jint sy1, jint sx2, jint sy2, - jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2 -) { - const jdouble epsilon = 0.0001f; - - // check that dx1,dy1 is integer - if (fabs(dx1 - (int)dx1) > epsilon || fabs(dy1 - (int)dy1) > epsilon) { - return JNI_FALSE; - } - // check that destSize equals srcSize - if (fabs(dx2 - dx1 - sx2 + sx1) > epsilon || fabs(dy2 - dy1 - sy2 + sy1) > epsilon) { - return JNI_FALSE; - } - return JNI_TRUE; -} - -static -jboolean clipDestCoords( - jdouble *dx1, jdouble *dy1, jdouble *dx2, jdouble *dy2, - jint *sx1, jint *sy1, jint *sx2, jint *sy2, - jint destW, jint destH, const MTLScissorRect * clipRect -) { - // Trim destination rect by clip-rect (or dest.bounds) - const jint sw = *sx2 - *sx1; - const jint sh = *sy2 - *sy1; - const jdouble dw = *dx2 - *dx1; - const jdouble dh = *dy2 - *dy1; - - jdouble dcx1 = 0; - jdouble dcx2 = destW; - jdouble dcy1 = 0; - jdouble dcy2 = destH; - if (clipRect != NULL) { - if (clipRect->x > dcx1) - dcx1 = clipRect->x; - const int maxX = clipRect->x + clipRect->width; - if (dcx2 > maxX) - dcx2 = maxX; - if (clipRect->y > dcy1) - dcy1 = clipRect->y; - const int maxY = clipRect->y + clipRect->height; - if (dcy2 > maxY) - dcy2 = maxY; - - if (dcx1 >= dcx2) { - J2dTraceLn2(J2D_TRACE_ERROR, "\tclipDestCoords: dcx1=%1.2f, dcx2=%1.2f", dcx1, dcx2); - dcx1 = dcx2; - } - if (dcy1 >= dcy2) { - J2dTraceLn2(J2D_TRACE_ERROR, "\tclipDestCoords: dcy1=%1.2f, dcy2=%1.2f", dcy1, dcy2); - dcy1 = dcy2; - } - } - if (*dx2 <= dcx1 || *dx1 >= dcx2 || *dy2 <= dcy1 || *dy1 >= dcy2) { - J2dTraceLn(J2D_TRACE_INFO, "\tclipDestCoords: dest rect doesn't intersect clip area"); - J2dTraceLn4(J2D_TRACE_INFO, "\tdx2=%1.4f <= dcx1=%1.4f || *dx1=%1.4f >= dcx2=%1.4f", *dx2, dcx1, *dx1, dcx2); - J2dTraceLn4(J2D_TRACE_INFO, "\t*dy2=%1.4f <= dcy1=%1.4f || *dy1=%1.4f >= dcy2=%1.4f", *dy2, dcy1, *dy1, dcy2); - return JNI_FALSE; - } - if (*dx1 < dcx1) { - J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdx1=%1.2f, will be clipped to %1.2f | sx1+=%d", *dx1, dcx1, (jint)((dcx1 - *dx1) * (sw/dw))); - *sx1 += (jint)((dcx1 - *dx1) * (sw/dw)); - *dx1 = dcx1; - } - if (*dx2 > dcx2) { - J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdx2=%1.2f, will be clipped to %1.2f | sx2-=%d", *dx2, dcx2, (jint)((*dx2 - dcx2) * (sw/dw))); - *sx2 -= (jint)((*dx2 - dcx2) * (sw/dw)); - *dx2 = dcx2; - } - if (*dy1 < dcy1) { - J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdy1=%1.2f, will be clipped to %1.2f | sy1+=%d", *dy1, dcy1, (jint)((dcy1 - *dy1) * (sh/dh))); - *sy1 += (jint)((dcy1 - *dy1) * (sh/dh)); - *dy1 = dcy1; - } - if (*dy2 > dcy2) { - J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdy2=%1.2f, will be clipped to %1.2f | sy2-=%d", *dy2, dcy2, (jint)((*dy2 - dcy2) * (sh/dh))); - *sy2 -= (jint)((*dy2 - dcy2) * (sh/dh)); - *dy2 = dcy2; - } - return JNI_TRUE; -} - -/** - * General blit method for copying a native MTL surface to another MTL "Surface". - * Parameter texture == true forces to use 'texture' codepath (dest coordinates will always be integers). - * Parameter xform == true only when AffineTransform is used (invoked only from TransformBlit, dest coordinates will always be integers). - */ -void -MTLBlitLoops_IsoBlit(JNIEnv *env, - MTLContext *mtlc, jlong pSrcOps, jlong pDstOps, - jboolean xform, jint hint, jboolean texture, - jint sx1, jint sy1, jint sx2, jint sy2, - jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2) -{ - BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrcOps); - BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDstOps); - - RETURN_IF_NULL(mtlc); - RETURN_IF_NULL(srcOps); - RETURN_IF_NULL(dstOps); - // Verify if we use a valid MTLContext - MTLSDOps *dstMTLOps = (MTLSDOps *)dstOps->privOps; - RETURN_IF_TRUE(dstMTLOps->configInfo != NULL && mtlc != dstMTLOps->configInfo->context); - - MTLSDOps *srcMTLOps = (MTLSDOps *)srcOps->privOps; - RETURN_IF_TRUE(srcMTLOps->configInfo != NULL && mtlc != srcMTLOps->configInfo->context); - - id<MTLTexture> srcTex = srcOps->pTexture; - id<MTLTexture> dstTex = dstOps->pTexture; - if (srcTex == nil || srcTex == nil) { - J2dTraceLn2(J2D_TRACE_ERROR, "MTLBlitLoops_IsoBlit: surface is null (stex=%p, dtex=%p)", srcTex, dstTex); - return; - } - - const jint sw = sx2 - sx1; - const jint sh = sy2 - sy1; - const jdouble dw = dx2 - dx1; - const jdouble dh = dy2 - dy1; - - if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0) { - J2dTraceLn4(J2D_TRACE_WARNING, "MTLBlitLoops_IsoBlit: invalid dimensions: sw=%d, sh%d, dw=%d, dh=%d", sw, sh, dw, dh); - return; - } - -#ifdef DEBUG_ISOBLIT - if ((xform == JNI_TRUE) != (mtlc.useTransform == JNI_TRUE)) { - J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE, - "MTLBlitLoops_IsoBlit state error: xform=%d, mtlc.useTransform=%d, texture=%d", - xform, mtlc.useTransform, texture); - } -#endif // DEBUG_ISOBLIT - - if (!xform) { - clipDestCoords( - &dx1, &dy1, &dx2, &dy2, - &sx1, &sy1, &sx2, &sy2, - dstTex.width, dstTex.height, texture ? NULL : [mtlc.clip getRect] - ); - } - - SurfaceDataBounds bounds; - bounds.x1 = sx1; - bounds.y1 = sy1; - bounds.x2 = sx2; - bounds.y2 = sy2; - SurfaceData_IntersectBoundsXYXY(&bounds, 0, 0, srcOps->width, srcOps->height); - - if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLBlitLoops_IsoBlit: source rectangle doesn't intersect with source surface bounds"); - J2dTraceLn6(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d sw=%d sh=%d", sx1, sy1, sx2, sy2, srcOps->width, srcOps->height); - J2dTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f", dx1, dy1, dx2, dy2); - return; - } - - if (bounds.x1 != sx1) { - dx1 += (bounds.x1 - sx1) * (dw / sw); - sx1 = bounds.x1; - } - if (bounds.y1 != sy1) { - dy1 += (bounds.y1 - sy1) * (dh / sh); - sy1 = bounds.y1; - } - if (bounds.x2 != sx2) { - dx2 += (bounds.x2 - sx2) * (dw / sw); - sx2 = bounds.x2; - } - if (bounds.y2 != sy2) { - dy2 += (bounds.y2 - sy2) * (dh / sh); - sy2 = bounds.y2; - } - -#ifdef TRACE_ISOBLIT - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, - "MTLBlitLoops_IsoBlit [tx=%d, xf=%d, AC=%s]: src=%s, dst=%s | (%d, %d, %d, %d)->(%1.2f, %1.2f, %1.2f, %1.2f)", - texture, xform, [mtlc getCompositeDescription].cString, - getSurfaceDescription(srcOps).cString, getSurfaceDescription(dstOps).cString, - sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); -#endif //TRACE_ISOBLIT - - if (!texture && !xform - && srcOps->isOpaque - && isIntegerAndUnscaled(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) - && (dstOps->isOpaque || !srcOps->isOpaque) - ) { -#ifdef TRACE_ISOBLIT - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE," [via blitEncoder]"); -#endif //TRACE_ISOBLIT - - id <MTLBlitCommandEncoder> blitEncoder = [mtlc.encoderManager createBlitEncoder]; - [blitEncoder copyFromTexture:srcTex - sourceSlice:0 - sourceLevel:0 - sourceOrigin:MTLOriginMake(sx1, sy1, 0) - sourceSize:MTLSizeMake(sx2 - sx1, sy2 - sy1, 1) - toTexture:dstTex - destinationSlice:0 - destinationLevel:0 - destinationOrigin:MTLOriginMake(dx1, dy1, 0)]; - [blitEncoder endEncoding]; - return; - } - -#ifdef TRACE_ISOBLIT - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE," [via sampling]"); -#endif //TRACE_ISOBLIT - drawTex2Tex(mtlc, srcTex, dstTex, - srcOps->isOpaque, dstOps->isOpaque, - hint, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); -} - -/** - * General blit method for copying a system memory ("Sw") surface to a native MTL surface. - * Parameter texture == true only in SwToTextureBlit (straight copy from sw to texture), dest coordinates will always be integers. - * Parameter xform == true only when AffineTransform is used (invoked only from TransformBlit, dest coordinates will always be integers). - */ -void -MTLBlitLoops_Blit(JNIEnv *env, - MTLContext *mtlc, jlong pSrcOps, jlong pDstOps, - jboolean xform, jint hint, - jint srctype, jboolean texture, - jint sx1, jint sy1, jint sx2, jint sy2, - jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2) -{ - SurfaceDataOps *srcOps = (SurfaceDataOps *)jlong_to_ptr(pSrcOps); - BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDstOps); - - RETURN_IF_NULL(mtlc); - RETURN_IF_NULL(srcOps); - RETURN_IF_NULL(dstOps); - // Verify if we use a valid MTLContext - MTLSDOps *dstMTLOps = (MTLSDOps *)dstOps->privOps; - RETURN_IF_TRUE(dstMTLOps->configInfo != NULL && mtlc != dstMTLOps->configInfo->context); - - id<MTLTexture> dest = dstOps->pTexture; - if (dest == NULL) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitLoops_Blit: dest is null"); - return; - } - if (srctype < 0 || srctype >= sizeof(RasterFormatInfos)/ sizeof(MTLRasterFormatInfo)) { - J2dTraceLn1(J2D_TRACE_ERROR, "MTLBlitLoops_Blit: source pixel format %d isn't supported", srctype); - return; - } - const jint sw = sx2 - sx1; - const jint sh = sy2 - sy1; - const jdouble dw = dx2 - dx1; - const jdouble dh = dy2 - dy1; - - if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitLoops_Blit: invalid dimensions"); - return; - } - -#ifdef DEBUG_BLIT - if ( - (xform == JNI_TRUE) != (mtlc.useTransform == JNI_TRUE) - || (xform && texture) - ) { - J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE, - "MTLBlitLoops_Blit state error: xform=%d, mtlc.useTransform=%d, texture=%d", - xform, mtlc.useTransform, texture); - } - if (texture) { - if (!isIntegerAndUnscaled(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2)) { - J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE, - "MTLBlitLoops_Blit state error: texture=true, but src and dst dimensions aren't equal or dest coords aren't integers"); - } - if (!dstOps->isOpaque && !RasterFormatInfos[srctype].hasAlpha) { - J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE, - "MTLBlitLoops_Blit state error: texture=true, but dest has alpha and source hasn't alpha, can't use texture-codepath"); - } - } -#endif // DEBUG_BLIT - if (!xform) { - clipDestCoords( - &dx1, &dy1, &dx2, &dy2, - &sx1, &sy1, &sx2, &sy2, - dest.width, dest.height, texture ? NULL : [mtlc.clip getRect] - ); - } - - SurfaceDataRasInfo srcInfo; - srcInfo.bounds.x1 = sx1; - srcInfo.bounds.y1 = sy1; - srcInfo.bounds.x2 = sx2; - srcInfo.bounds.y2 = sy2; - - // NOTE: This function will modify the contents of the bounds field to represent the maximum available raster data. - if (srcOps->Lock(env, srcOps, &srcInfo, SD_LOCK_READ) != SD_SUCCESS) { - J2dTraceLn(J2D_TRACE_WARNING, "MTLBlitLoops_Blit: could not acquire lock"); - return; - } - - if (srcInfo.bounds.x2 > srcInfo.bounds.x1 && srcInfo.bounds.y2 > srcInfo.bounds.y1) { - srcOps->GetRasInfo(env, srcOps, &srcInfo); - if (srcInfo.rasBase) { - if (srcInfo.bounds.x1 != sx1) { - const int dx = srcInfo.bounds.x1 - sx1; - dx1 += dx * (dw / sw); - } - if (srcInfo.bounds.y1 != sy1) { - const int dy = srcInfo.bounds.y1 - sy1; - dy1 += dy * (dh / sh); - } - if (srcInfo.bounds.x2 != sx2) { - const int dx = srcInfo.bounds.x2 - sx2; - dx2 += dx * (dw / sw); - } - if (srcInfo.bounds.y2 != sy2) { - const int dy = srcInfo.bounds.y2 - sy2; - dy2 += dy * (dh / sh); - } - -#ifdef TRACE_BLIT - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, - "MTLBlitLoops_Blit [tx=%d, xf=%d, AC=%s]: bdst=%s, src=%p (%dx%d) O=%d premul=%d | (%d, %d, %d, %d)->(%1.2f, %1.2f, %1.2f, %1.2f)", - texture, xform, [mtlc getCompositeDescription].cString, - getSurfaceDescription(dstOps).cString, srcOps, - sx2 - sx1, sy2 - sy1, - RasterFormatInfos[srctype].hasAlpha ? 0 : 1, RasterFormatInfos[srctype].isPremult ? 1 : 0, - sx1, sy1, sx2, sy2, - dx1, dy1, dx2, dy2); -#endif //TRACE_BLIT - - MTLRasterFormatInfo rfi = RasterFormatInfos[srctype]; - - if (texture) { - replaceTextureRegion(mtlc, dest, &srcInfo, &rfi, (int) dx1, (int) dy1, (int) dx2, (int) dy2); - } else { - MTLBlitSwToTextureViaPooledTexture(mtlc, &srcInfo, dstOps, &rfi, hint, dx1, dy1, dx2, dy2); - } - } - SurfaceData_InvokeRelease(env, srcOps, &srcInfo); - } - SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); -} - -void copyFromMTLBuffer(void *pDst, id<MTLBuffer> srcBuf, NSUInteger offset, NSUInteger len, BOOL convertFromArgbPre) { - char *pSrc = (char*)srcBuf.contents + offset; - if (convertFromArgbPre) { - NSUInteger pixelLen = len >> 2; - for (NSUInteger i = 0; i < pixelLen; i++) { - LoadIntArgbPreTo1IntArgb((jint*)pSrc, 0, i, ((jint*)pDst)[i]); - } - } else { - memcpy(pDst, pSrc, len); - } -} - -/** - * Specialized blit method for copying a native MTL "Surface" (pbuffer, - * window, etc.) to a system memory ("Sw") surface. - */ -void -MTLBlitLoops_SurfaceToSwBlit(JNIEnv *env, MTLContext *mtlc, - jlong pSrcOps, jlong pDstOps, jint dsttype, - jint srcx, jint srcy, jint dstx, jint dsty, - jint width, jint height) -{ - J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLBlitLoops_SurfaceToSwBlit: sx=%d sy=%d w=%d h=%d dx=%d dy=%d", srcx, srcy, width, height, dstx, dsty); - - BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrcOps); - SurfaceDataOps *dstOps = (SurfaceDataOps *)jlong_to_ptr(pDstOps); - SurfaceDataRasInfo srcInfo, dstInfo; - - if (dsttype < 0 || dsttype >= sizeof(RasterFormatInfos)/ sizeof(MTLRasterFormatInfo)) { - J2dTraceLn1(J2D_TRACE_ERROR, "MTLBlitLoops_SurfaceToSwBlit: destination pixel format %d isn't supported", dsttype); - return; - } - - if (width <= 0 || height <= 0) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitLoops_SurfaceToSwBlit: dimensions are non-positive"); - return; - } - - RETURN_IF_NULL(srcOps); - RETURN_IF_NULL(dstOps); - RETURN_IF_NULL(mtlc); - RETURN_IF_TRUE(width < 0); - RETURN_IF_TRUE(height < 0); - NSUInteger w = (NSUInteger)width; - NSUInteger h = (NSUInteger)height; - - srcInfo.bounds.x1 = srcx; - srcInfo.bounds.y1 = srcy; - srcInfo.bounds.x2 = srcx + width; - srcInfo.bounds.y2 = srcy + height; - dstInfo.bounds.x1 = dstx; - dstInfo.bounds.y1 = dsty; - dstInfo.bounds.x2 = dstx + width; - dstInfo.bounds.y2 = dsty + height; - - if (dstOps->Lock(env, dstOps, &dstInfo, SD_LOCK_WRITE) != SD_SUCCESS) { - J2dTraceLn(J2D_TRACE_WARNING,"MTLBlitLoops_SurfaceToSwBlit: could not acquire dst lock"); - return; - } - - SurfaceData_IntersectBoundsXYXY(&srcInfo.bounds, - 0, 0, srcOps->width, srcOps->height); - - SurfaceData_IntersectBlitBounds(&dstInfo.bounds, &srcInfo.bounds, - srcx - dstx, srcy - dsty); - - if (srcInfo.bounds.x2 > srcInfo.bounds.x1 && - srcInfo.bounds.y2 > srcInfo.bounds.y1) - { - dstOps->GetRasInfo(env, dstOps, &dstInfo); - if (dstInfo.rasBase) { - void *pDst = dstInfo.rasBase; - - srcx = srcInfo.bounds.x1; - srcy = srcInfo.bounds.y1; - dstx = dstInfo.bounds.x1; - dsty = dstInfo.bounds.y1; - width = srcInfo.bounds.x2 - srcInfo.bounds.x1; - height = srcInfo.bounds.y2 - srcInfo.bounds.y1; - - pDst = PtrPixelsRow(pDst, dstx, dstInfo.pixelStride); - pDst = PtrPixelsRow(pDst, dsty, dstInfo.scanStride); - - NSUInteger byteLength = w * h * 4; // NOTE: assume that src format is MTLPixelFormatBGRA8Unorm - - // Create MTLBuffer (or use static) - id<MTLBuffer> mtlbuf; -#ifdef USE_STATIC_BUFFER - // NOTE: theoretically we can use newBufferWithBytesNoCopy, but pDst must be allocated with special API - // mtlbuf = [mtlc.device - // newBufferWithBytesNoCopy:pDst - // length:(NSUInteger) srcLength - // options:MTLResourceCPUCacheModeDefaultCache - // deallocator:nil]; - // - // see https://developer.apple.com/documentation/metal/mtldevice/1433382-newbufferwithbytesnocopy?language=objc - // - // The storage allocation of the returned new MTLBuffer object is the same as the pointer input value. - // The existing memory allocation must be covered by a single VM region, typically allocated with vm_allocate or mmap. - // Memory allocated by malloc is specifically disallowed. - - static id<MTLBuffer> mtlIntermediateBuffer = nil; // need to reimplement with MTLBufferManager - if (mtlIntermediateBuffer == nil || mtlIntermediateBuffer.length < srcLength) { - if (mtlIntermediateBuffer != nil) { - [mtlIntermediateBuffer release]; - } - mtlIntermediateBuffer = [mtlc.device newBufferWithLength:srcLength options:MTLResourceCPUCacheModeDefaultCache]; - } - mtlbuf = mtlIntermediateBuffer; -#else // USE_STATIC_BUFFER - mtlbuf = [mtlc.device newBufferWithLength:byteLength options:MTLResourceStorageModeShared]; -#endif // USE_STATIC_BUFFER - - // Read from surface into MTLBuffer - // NOTE: using of separate blitCommandBuffer can produce errors (draw into surface (with general cmd-buf) - // can be unfinished when reading raster from blit cmd-buf). - // Consider to use [mtlc.encoderManager createBlitEncoder] and [mtlc commitCommandBuffer:JNI_TRUE]; - J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLBlitLoops_SurfaceToSwBlit: source texture %p", srcOps->pTexture); - - id<MTLCommandBuffer> cb = [mtlc createCommandBuffer]; - id<MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder]; - [blitEncoder copyFromTexture:srcOps->pTexture - sourceSlice:0 - sourceLevel:0 - sourceOrigin:MTLOriginMake(srcx, srcy, 0) - sourceSize:MTLSizeMake(w, h, 1) - toBuffer:mtlbuf - destinationOffset:0 /*offset already taken in: pDst = PtrPixelsRow(pDst, dstx, dstInfo.pixelStride)*/ - destinationBytesPerRow:w*4 - destinationBytesPerImage:byteLength]; - [blitEncoder endEncoding]; - - // Commit and wait for reading complete - [cb commit]; - [cb waitUntilCompleted]; - - // Perform conversion if necessary - BOOL convertFromPre = !RasterFormatInfos[dsttype].isPremult && !srcOps->isOpaque; - - if ((dstInfo.scanStride == w * dstInfo.pixelStride) && - (height == (dstInfo.bounds.y2 - dstInfo.bounds.y1))) { - // mtlbuf.contents have same dimensions as of pDst - copyFromMTLBuffer(pDst, mtlbuf, 0, byteLength, convertFromPre); - } else { - // mtlbuf.contents have smaller dimensions than pDst - // copy each row from mtlbuf.contents at appropriate position in pDst - // Note : pDst is already addjusted for offsets using PtrAddBytes above - - NSUInteger rowSize = w * dstInfo.pixelStride; - for (int y = 0; y < height; y++) { - copyFromMTLBuffer(pDst, mtlbuf, y * rowSize, rowSize, convertFromPre); - pDst = PtrAddBytes(pDst, dstInfo.scanStride); - } - } - -#ifndef USE_STATIC_BUFFER - [mtlbuf release]; -#endif // USE_STATIC_BUFFER - } - SurfaceData_InvokeRelease(env, dstOps, &dstInfo); - } - SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); -} - -void -MTLBlitLoops_CopyArea(JNIEnv *env, - MTLContext *mtlc, BMTLSDOps *dstOps, - jint x, jint y, jint width, jint height, - jint dx, jint dy) -{ -#ifdef DEBUG - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, "MTLBlitLoops_CopyArea: bdst=%p [tex=%p] %dx%d | src (%d, %d), %dx%d -> dst (%d, %d)", - dstOps, dstOps->pTexture, ((id<MTLTexture>)dstOps->pTexture).width, ((id<MTLTexture>)dstOps->pTexture).height, x, y, width, height, dx, dy); -#endif //DEBUG - jint texWidth = ((id<MTLTexture>)dstOps->pTexture).width; - jint texHeight = ((id<MTLTexture>)dstOps->pTexture).height; - - SurfaceDataBounds srcBounds, dstBounds; - srcBounds.x1 = x; - srcBounds.y1 = y; - srcBounds.x2 = srcBounds.x1 + width; - srcBounds.y2 = srcBounds.y1 + height; - dstBounds.x1 = x + dx; - dstBounds.y1 = y + dy; - dstBounds.x2 = dstBounds.x1 + width; - dstBounds.y2 = dstBounds.y1 + height; - - SurfaceData_IntersectBoundsXYXY(&srcBounds, 0, 0, texWidth, texHeight); - SurfaceData_IntersectBoundsXYXY(&dstBounds, 0, 0, texWidth, texHeight); - SurfaceData_IntersectBlitBounds(&dstBounds, &srcBounds, -dx, -dy); - - int srcWidth = (srcBounds.x2 - srcBounds.x1); - int srcHeight = (srcBounds.y2 - srcBounds.y1); - - if ((srcBounds.x1 < srcBounds.x2 && srcBounds.y1 < srcBounds.y2) && - (dstBounds.x1 < dstBounds.x2 && dstBounds.y1 < dstBounds.y2)) - { - @autoreleasepool { - struct TxtVertex quadTxVerticesBuffer[6]; - MTLPooledTextureHandle * interHandle = - [mtlc.texturePool getTexture:texWidth - height:texHeight - format:MTLPixelFormatBGRA8Unorm]; - if (interHandle == nil) { - J2dTraceLn(J2D_TRACE_ERROR, - "MTLBlitLoops_CopyArea: texture handle is null"); - return; - } - [[mtlc getCommandBufferWrapper] registerPooledTexture:interHandle]; - - id<MTLTexture> interTexture = interHandle.texture; - - /* - * We need to consider common states like clipping while - * performing copyArea, thats why we use drawTex2Tex and - * get encoder with appropriate state from EncoderManager - * and not directly use MTLBlitCommandEncoder for texture copy. - */ - - // copy content to intermediate texture - drawTex2Tex(mtlc, dstOps->pTexture, interTexture, dstOps->isOpaque, - JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, - 0, 0, texWidth, texHeight, 0, 0, texWidth, texHeight); - - // copy content with appropriate bounds to destination texture - drawTex2Tex(mtlc, interTexture, dstOps->pTexture, JNI_FALSE, - dstOps->isOpaque, INTERPOLATION_NEAREST_NEIGHBOR, - srcBounds.x1, srcBounds.y1, srcBounds.x2, srcBounds.y2, - dstBounds.x1, dstBounds.y1, dstBounds.x2, dstBounds.y2); - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper * cbwrapper = - [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - } - } -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.h deleted file mode 100644 index 18d822c377f..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLBufImgOps_h_Included -#define MTLBufImgOps_h_Included - -#include "MTLContext.h" - -@interface MTLRescaleOp : NSObject -- (id)init:(jboolean)isNonPremult factors:(unsigned char *)factors offsets:(unsigned char *)offsets; -- (jfloat *)getScaleFactors; -- (jfloat *)getOffsets; -- (NSString *)getDescription; // creates autorelease string - -@property (readonly) jboolean isNonPremult; -@end - -@interface MTLConvolveOp : NSObject -- (id)init:(jboolean)edgeZeroFill kernelWidth:(jint)kernelWidth - kernelHeight:(jint)kernelHeight - srcWidth:(jint)srcWidth - srcHeight:(jint)srcHeight - kernel:(unsigned char *)kernel - device:(id<MTLDevice>)device; -- (void) dealloc; - -- (id<MTLBuffer>) getBuffer; -- (const float *) getImgEdge; -- (NSString *)getDescription; // creates autorelease string - -@property (readonly) jboolean isEdgeZeroFill; -@property (readonly) int kernelSize; -@end - -@interface MTLLookupOp : NSObject -- (id)init:(jboolean)nonPremult shortData:(jboolean)shortData - numBands:(jint)numBands - bandLength:(jint)bandLength - offset:(jint)offset - tableValues:(void *)tableValues - device:(id<MTLDevice>)device; -- (void) dealloc; - -- (jfloat *)getOffset; -- (id<MTLTexture>) getLookupTexture; -- (NSString *)getDescription; // creates autorelease string - -@property (readonly) jboolean isUseSrcAlpha; -@property (readonly) jboolean isNonPremult; -@end - -#endif /* MTLBufImgOps_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.m deleted file mode 100644 index a36e211f748..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.m +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <jlong.h> - -#include "MTLBufImgOps.h" -#include "MTLContext.h" -#include "MTLRenderQueue.h" -#include "MTLSurfaceDataBase.h" -#include "GraphicsPrimitiveMgr.h" - -@implementation MTLRescaleOp { - jboolean _isNonPremult; - jfloat _normScaleFactors[4]; - jfloat _normOffsets[4]; -} - --(jfloat *) getScaleFactors { - return _normScaleFactors; -} --(jfloat *) getOffsets { - return _normOffsets; -} - -- (id)init:(jboolean)isNonPremult factors:(unsigned char *)factors offsets:(unsigned char *)offsets { - self = [super init]; - if (self) { - J2dTraceLn1(J2D_TRACE_INFO,"Created MTLRescaleOp: isNonPremult=%d", isNonPremult); - - _isNonPremult = isNonPremult; - _normScaleFactors[0] = NEXT_FLOAT(factors); - _normScaleFactors[1] = NEXT_FLOAT(factors); - _normScaleFactors[2] = NEXT_FLOAT(factors); - _normScaleFactors[3] = NEXT_FLOAT(factors); - _normOffsets[0] = NEXT_FLOAT(offsets); - _normOffsets[1] = NEXT_FLOAT(offsets); - _normOffsets[2] = NEXT_FLOAT(offsets); - _normOffsets[3] = NEXT_FLOAT(offsets); - } - return self; -} - -- (NSString *)getDescription { - return [NSString stringWithFormat:@"rescale: nonPremult=%d", _isNonPremult]; -} -@end - -@implementation MTLConvolveOp { - id<MTLBuffer> _buffer; - float _imgEdge[4]; - int _kernelSize; - jboolean _isEdgeZeroFill; -} - -- (id)init:(jboolean)edgeZeroFill kernelWidth:(jint)kernelWidth - kernelHeight:(jint)kernelHeight - srcWidth:(jint)srcWidth - srcHeight:(jint)srcHeight - kernel:(unsigned char *)kernel - device:(id<MTLDevice>)device { - self = [super init]; - if (self) { - J2dTraceLn2(J2D_TRACE_INFO,"Created MTLConvolveOp: kernelW=%d kernelH=%d", kernelWidth, kernelHeight); - _isEdgeZeroFill = edgeZeroFill; - - _kernelSize = kernelWidth * kernelHeight; - _buffer = [device newBufferWithLength:_kernelSize*sizeof(vector_float3) options:MTLResourceStorageModeShared]; - - float * kernelVals = [_buffer contents]; - int kIndex = 0; - for (int i = -kernelHeight/2; i < kernelHeight/2+1; i++) { - for (int j = -kernelWidth/2; j < kernelWidth/2+1; j++) { - kernelVals[kIndex+0] = j/(float)srcWidth; - kernelVals[kIndex+1] = i/(float)srcHeight; - kernelVals[kIndex+2] = NEXT_FLOAT(kernel); - kIndex += 3; - } - } - - _imgEdge[0] = (kernelWidth/2)/(float)srcWidth; - _imgEdge[1] = (kernelHeight/2)/(float)srcHeight; - _imgEdge[2] = 1 - _imgEdge[0]; - _imgEdge[3] = 1 - _imgEdge[1]; - } - return self; -} - -- (void) dealloc { - [_buffer release]; - [super dealloc]; -} - -- (id<MTLBuffer>) getBuffer { - return _buffer; -} - -- (const float *) getImgEdge { - return _imgEdge; -} - -- (NSString *)getDescription { - return [NSString stringWithFormat:@"convolve: isEdgeZeroFill=%d", _isEdgeZeroFill]; -} -@end - - -@implementation MTLLookupOp { - float _offset[4]; - jboolean _isUseSrcAlpha; - jboolean _isNonPremult; - - id<MTLTexture> _lookupTex; -} - -- (id)init:(jboolean)nonPremult shortData:(jboolean)shortData - numBands:(jint)numBands - bandLength:(jint)bandLength - offset:(jint)offset - tableValues:(void *)tableValues - device:(id<MTLDevice>)device { - self = [super init]; - if (self) { - J2dTraceLn4(J2D_TRACE_INFO,"Created MTLLookupOp: short=%d num=%d len=%d off=%d", - shortData, numBands, bandLength, offset); - - _isUseSrcAlpha = numBands != 4; - _isNonPremult = nonPremult; - - _offset[0] = offset / 255.0f; - _offset[1] = _offset[0]; - _offset[2] = _offset[0]; - _offset[3] = _offset[0]; - - MTLTextureDescriptor *textureDescriptor = - [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatA8Unorm - width:(NSUInteger)256 - height:(NSUInteger)4 - mipmapped:NO]; - - _lookupTex = [device newTextureWithDescriptor:textureDescriptor]; - - void *bands[4]; - for (int i = 0; i < 4; i++) { - bands[i] = NULL; - } - int bytesPerElem = (shortData ? 2 : 1); - if (numBands == 1) { - // replicate the single band for R/G/B; alpha band is unused - for (int i = 0; i < 3; i++) { - bands[i] = tableValues; - } - bands[3] = NULL; - } else if (numBands == 3) { - // user supplied band for each of R/G/B; alpha band is unused - for (int i = 0; i < 3; i++) { - bands[i] = PtrPixelsBand(tableValues, i, bandLength, bytesPerElem); - } - bands[3] = NULL; - } else if (numBands == 4) { - // user supplied band for each of R/G/B/A - for (int i = 0; i < 4; i++) { - bands[i] = PtrPixelsBand(tableValues, i, bandLength, bytesPerElem); - } - } - - for (int i = 0; i < 4; i++) { - if (bands[i] == NULL) - continue; - - MTLRegion region = { - {0, i, 0}, - {bandLength, 1,1} - }; - - [_lookupTex replaceRegion:region - mipmapLevel:0 - withBytes:bands[i] - bytesPerRow:bandLength*bytesPerElem]; - } - } - return self; -} - -- (void) dealloc { - [_lookupTex release]; - [super dealloc]; -} - -- (jfloat *) getOffset { - return _offset; -} - -- (id<MTLTexture>) getLookupTexture { - return _lookupTex; -} - -- (NSString *)getDescription { - return [NSString stringWithFormat:@"lookup: offset=%f", _offset[0]]; -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.h deleted file mode 100644 index 0b193f975aa..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#import <limits.h> -#ifndef MTLClip_h_Included -#define MTLClip_h_Included - -#import <Metal/Metal.h> - -#include <jni.h> - -#include "MTLSurfaceDataBase.h" - -enum Clip { - NO_CLIP, - RECT_CLIP, - SHAPE_CLIP -}; - -@class MTLContext; -@class MTLPipelineStatesStorage; - -/** - * The MTLClip class represents clip mode (rect or stencil) - * */ - -@interface MTLClip : NSObject -@property (readonly) id<MTLTexture> stencilTextureRef; -@property (readonly) BOOL stencilMaskGenerationInProgress; -@property (readwrite ) BOOL stencilMaskGenerationStarted; -@property NSUInteger shapeX; -@property NSUInteger shapeY; -@property NSUInteger shapeWidth; -@property NSUInteger shapeHeight; -@property (readonly) BMTLSDOps* dstOps; - -- (id)init; -- (BOOL)isEqual:(MTLClip *)other; // used to compare requested with cached -- (void)copyFrom:(MTLClip *)other; // used to save cached - -- (BOOL)isShape; -- (BOOL)isRect; - -// returns null when clipType != RECT_CLIP -- (const MTLScissorRect *) getRect; - -- (void)reset; -- (void)resetStencilState; -- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2; -- (void)beginShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc; -- (void)endShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc; - -- (void)setScissorOrStencil:(id<MTLRenderCommandEncoder>)encoder - destWidth:(NSUInteger)dw - destHeight:(NSUInteger)dh - device:(id<MTLDevice>)device; - -- (void)setMaskGenerationPipelineState:(id<MTLRenderCommandEncoder>)encoder - destWidth:(NSUInteger)dw - destHeight:(NSUInteger)dh - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage; - -- (NSString *)getDescription __unused; // creates autorelease string -@end - -#endif // MTLClip_h_Included diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m deleted file mode 100644 index 35d8ba624c9..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "MTLClip.h" - -#include "MTLContext.h" -#include "MTLStencilManager.h" -#include "common.h" - -static MTLRenderPipelineDescriptor * templateStencilPipelineDesc = nil; - -static void initTemplatePipelineDescriptors() { - if (templateStencilPipelineDesc != nil) - return; - - MTLVertexDescriptor *vertDesc = [[MTLVertexDescriptor new] autorelease]; - vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat2; - vertDesc.attributes[VertexAttributePosition].offset = 0; - vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer; - vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct Vertex); - vertDesc.layouts[MeshVertexBuffer].stepRate = 1; - vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex; - - templateStencilPipelineDesc = [MTLRenderPipelineDescriptor new]; - templateStencilPipelineDesc.sampleCount = 1; - templateStencilPipelineDesc.vertexDescriptor = vertDesc; - templateStencilPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatR8Uint; // A byte buffer format - templateStencilPipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatStencil8; - templateStencilPipelineDesc.label = @"template_stencil"; -} - -@implementation MTLClip { - jint _clipType; - MTLScissorRect _clipRect; - MTLContext* _mtlc; - BMTLSDOps* _dstOps; - BOOL _stencilMaskGenerationInProgress; - BOOL _stencilMaskGenerationStarted; - BOOL _clipReady; - MTLOrigin _clipShapeOrigin; - MTLSize _clipShapeSize; -} - -@synthesize dstOps = _dstOps; - -- (id)init { - self = [super init]; - if (self) { - _clipType = NO_CLIP; - _mtlc = nil; - _dstOps = NULL; - _stencilMaskGenerationInProgress = NO; - _stencilMaskGenerationStarted = NO; - _clipReady = NO; - } - return self; -} - -- (BOOL)isEqual:(MTLClip *)other { - if (self == other) - return YES; - if (_stencilMaskGenerationInProgress == JNI_TRUE) - return other->_stencilMaskGenerationInProgress == JNI_TRUE; - if (_clipType != other->_clipType) - return NO; - if (_clipType == NO_CLIP) - return YES; - if (_clipType == RECT_CLIP) { - return _clipRect.x == other->_clipRect.x && _clipRect.y == other->_clipRect.y - && _clipRect.width == other->_clipRect.width && _clipRect.height == other->_clipRect.height; - } - - // NOTE: can compare stencil-data pointers here - return YES; -} - -- (BOOL)isShape { - return _clipType == SHAPE_CLIP; -} - -- (BOOL)isRect __unused { - return _clipType == RECT_CLIP; -} - -- (const MTLScissorRect * _Nullable) getRect { - return _clipType == RECT_CLIP ? &_clipRect : NULL; -} - -- (void)copyFrom:(MTLClip *)other { - _clipType = other->_clipType; - _stencilMaskGenerationInProgress = other->_stencilMaskGenerationInProgress; - _dstOps = other->_dstOps; - _mtlc = other->_mtlc; - if (other->_clipType == RECT_CLIP) { - _clipRect = other->_clipRect; - } -} - -- (void)reset { - _clipType = NO_CLIP; - _stencilMaskGenerationInProgress = JNI_FALSE; -} - - -- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2 { - if (_clipType == SHAPE_CLIP) { - _dstOps = NULL; - } - - if (x1 >= x2 || y1 >= y2) { - J2dTraceLn4(J2D_TRACE_ERROR, "MTLClip.setClipRect: invalid rect: x1=%d y1=%d x2=%d y2=%d", x1, y1, x2, y2); - _clipType = NO_CLIP; - } - - const jint width = x2 - x1; - const jint height = y2 - y1; - - J2dTraceLn4(J2D_TRACE_INFO, "MTLClip.setClipRect: x=%d y=%d w=%d h=%d", x1, y1, width, height); - - _clipRect.x = (NSUInteger)((x1 >= 0) ? x1 : 0); - _clipRect.y = (NSUInteger)((y1 >= 0) ? y1 : 0); - _clipRect.width = (NSUInteger)((width >= 0) ? width : 0); - _clipRect.height = (NSUInteger)((height >= 0) ? height : 0); - _clipType = RECT_CLIP; -} - -- (void)beginShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc { - _stencilMaskGenerationInProgress = YES; - _mtlc = mtlc; - if ((dstOps == NULL) || (dstOps->pStencilData == NULL) || (dstOps->pStencilTexture == NULL)) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_beginShapeClip: stencil render target or stencil texture is NULL"); - return; - } - - // Clear the stencil render buffer & stencil texture - @autoreleasepool { - if (dstOps->width <= 0 || dstOps->height <= 0) { - return; - } - - _clipShapeSize = MTLSizeMake(0, 0, 1); - // Use out of bounds origin to correctly calculate shape boundaries - _clipShapeOrigin = MTLOriginMake((NSUInteger) dstOps->width, (NSUInteger) dstOps->height, 0); - _dstOps = dstOps; - } -} - -- (void)endShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc { - - if ((dstOps == NULL) || (dstOps->pStencilData == NULL) || (dstOps->pStencilTexture == NULL)) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_endShapeClip: stencil render target or stencil texture is NULL"); - return; - } - - // Complete the rendering to the stencil buffer ------------ - [mtlc.encoderManager endEncoder]; - - MTLCommandBufferWrapper* cbWrapper = [mtlc pullCommandBufferWrapper]; - - id<MTLCommandBuffer> commandBuffer = [cbWrapper getCommandBuffer]; - [commandBuffer addCompletedHandler:^(id <MTLCommandBuffer> c) { - [cbWrapper release]; - }]; - - [commandBuffer commit]; - _stencilMaskGenerationInProgress = NO; - _stencilMaskGenerationStarted = NO; - _dstOps = dstOps; - _clipType = SHAPE_CLIP; - _clipReady = NO; -} - -- (void)setMaskGenerationPipelineState:(id<MTLRenderCommandEncoder>)encoder - destWidth:(NSUInteger)dw - destHeight:(NSUInteger)dh - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - - // A PipelineState for rendering to a byte-buffered texture that will be used as a stencil - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:templateStencilPipelineDesc - vertexShaderId:@"vert_stencil" - fragmentShaderId:@"frag_stencil" - stencilNeeded:YES]; - [encoder setRenderPipelineState:pipelineState]; - - struct FrameUniforms uf; // color is ignored while writing to stencil buffer - memset(&uf, 0, sizeof(uf)); - [encoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - - _clipRect.x = 0; - _clipRect.y = 0; - _clipRect.width = dw; - _clipRect.height = dh; - - [encoder setDepthStencilState: _mtlc.stencilManager.genStencilState]; - [encoder setStencilReferenceValue:255]; - [encoder setScissorRect:_clipRect]; // just for insurance (to reset possible clip from previous drawing) -} - -- (void)setScissorOrStencil:(id<MTLRenderCommandEncoder>)encoder - destWidth:(NSUInteger)dw - destHeight:(NSUInteger)dh - device:(id<MTLDevice>)device -{ - if (_clipType == NO_CLIP || _clipType == SHAPE_CLIP) { - _clipRect.x = 0; - _clipRect.y = 0; - _clipRect.width = dw; - _clipRect.height = dh; - } - - // Clamping clip rect to the destination area - MTLScissorRect rect = _clipRect; - - if (rect.x > dw) { - rect.x = dw; - } - - if (rect.y > dh) { - rect.y = dh; - } - - if (rect.x + rect.width > dw) { - rect.width = dw - rect.x; - } - - if (rect.y + rect.height > dh) { - rect.height = dh - rect.y; - } - - [encoder setScissorRect:rect]; - if (_clipType == NO_CLIP || _clipType == RECT_CLIP) { - // NOTE: It seems that we can use the same encoder (with disabled stencil test) when mode changes from SHAPE to RECT. - // But [encoder setDepthStencilState:nil] causes crash, so we have to recreate encoder in such case. - // So we can omit [encoder setDepthStencilState:nil] here. - return; - } - - if (_clipType == SHAPE_CLIP) { - // Enable stencil test - [encoder setDepthStencilState:_mtlc.stencilManager.stencilState]; - [encoder setStencilReferenceValue:0xFF]; - } -} - -- (NSString *)getDescription __unused { - if (_clipType == NO_CLIP) { - return @"NO_CLIP"; - } - if (_clipType == RECT_CLIP) { - return [NSString stringWithFormat:@"RECT_CLIP [%lu,%lu - %lux%lu]", _clipRect.x, _clipRect.y, _clipRect.width, _clipRect.height]; - } - return [NSString stringWithFormat:@"SHAPE_CLIP"]; -} - -- (id<MTLTexture>) stencilTextureRef { - if (_dstOps == NULL) return nil; - - return _dstOps->pStencilTexture;; -} - -- (NSUInteger)shapeX { - return _clipShapeOrigin.x; -} - -- (void)setShapeX:(NSUInteger)shapeX { - _clipShapeOrigin.x = shapeX; -} - -- (NSUInteger)shapeY { - return _clipShapeOrigin.y; -} - -- (void)setShapeY:(NSUInteger)shapeY { - _clipShapeOrigin.y = shapeY; -} - -- (NSUInteger)shapeWidth { - return _clipShapeSize.width; -} - -- (void)setShapeWidth:(NSUInteger)shapeWidth { - _clipShapeSize.width = shapeWidth; -} - -- (NSUInteger)shapeHeight { - return _clipShapeSize.height; -} - -- (void)setShapeHeight:(NSUInteger)shapeHeight { - _clipShapeSize.height = shapeHeight; -} - - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.h deleted file mode 100644 index e792ca1d4ab..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLComposite_h_Included -#define MTLComposite_h_Included - -#import <Metal/Metal.h> - -#include <jni.h> - -#define FLT_EPS (0.001f) -#define FLT_LT(x,y) ((x) < (y) - FLT_EPS) -#define FLT_GE(x,y) ((x) >= (y) - FLT_EPS) -#define FLT_LE(x,y) ((x) <= (y) + FLT_EPS) -#define FLT_GT(x,y) ((x) > (y) + FLT_EPS) - -/** - * The MTLComposite class represents composite mode - * */ - -@interface MTLComposite : NSObject -- (id)init; -- (BOOL)isEqual:(MTLComposite *)other; // used to compare requested with cached -- (void)copyFrom:(MTLComposite *)other; // used to save cached - -- (void)setRule:(jint)rule; // sets extraAlpha=1 -- (void)setRule:(jint)rule extraAlpha:(jfloat)extraAlpha; -- (void)reset; - -- (void)setXORComposite:(jint)color; -- (void)setAlphaComposite:(jint)rule; - - -- (jint)getCompositeState; -- (jint)getRule; -- (jint)getXorColor; -- (jfloat)getExtraAlpha; - -- (NSString *)getDescription; // creates autorelease string -@end - -#endif // MTLComposite_h_Included diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.m deleted file mode 100644 index 83a9230b168..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLComposite.m +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "MTLComposite.h" -#include "sun_java2d_SunGraphics2D.h" -#include "java_awt_AlphaComposite.h" - -@implementation MTLComposite { - jint _compState; - jint _compositeRule; - jint _xorPixel; - jfloat _extraAlpha; -} - -- (id)init { - self = [super init]; - if (self) { - _compositeRule = -1; - _compState = -1; - _xorPixel = 0; - _extraAlpha = 1; - } - return self; -} - -- (BOOL)isEqual:(MTLComposite *)other { - if (self == other) - return YES; - - if (_compState == other->_compState) { - if (_compState == sun_java2d_SunGraphics2D_COMP_XOR) { - return _xorPixel == other->_xorPixel; - } - - if (_compState == sun_java2d_SunGraphics2D_COMP_ALPHA) { - return _extraAlpha == other->_extraAlpha - && _compositeRule == other->_compositeRule; - } - } - - return NO; -} - -- (void)copyFrom:(MTLComposite *)other { - _extraAlpha = other->_extraAlpha; - _compositeRule = other->_compositeRule; - _compState = other->_compState; - _xorPixel = other->_xorPixel; -} - -- (void)setRule:(jint)rule { - _extraAlpha = 1.f; - _compositeRule = rule; -} - -- (void)setRule:(jint)rule extraAlpha:(jfloat)extraAlpha { - _compState = sun_java2d_SunGraphics2D_COMP_ALPHA; - _extraAlpha = extraAlpha; - _compositeRule = rule; -} - -- (void)reset { - _compState = sun_java2d_SunGraphics2D_COMP_ISCOPY; - _compositeRule = java_awt_AlphaComposite_SRC; - _extraAlpha = 1.f; -} - -- (jint)getRule { - return _compositeRule; -} - -- (NSString *)getDescription { - const char * result = ""; - switch (_compositeRule) { - case java_awt_AlphaComposite_CLEAR: - { - result = "CLEAR"; - } - break; - case java_awt_AlphaComposite_SRC: - { - result = "SRC"; - } - break; - case java_awt_AlphaComposite_DST: - { - result = "DST"; - } - break; - case java_awt_AlphaComposite_SRC_OVER: - { - result = "SRC_OVER"; - } - break; - case java_awt_AlphaComposite_DST_OVER: - { - result = "DST_OVER"; - } - break; - case java_awt_AlphaComposite_SRC_IN: - { - result = "SRC_IN"; - } - break; - case java_awt_AlphaComposite_DST_IN: - { - result = "DST_IN"; - } - break; - case java_awt_AlphaComposite_SRC_OUT: - { - result = "SRC_OUT"; - } - break; - case java_awt_AlphaComposite_DST_OUT: - { - result = "DST_OUT"; - } - break; - case java_awt_AlphaComposite_SRC_ATOP: - { - result = "SRC_ATOP"; - } - break; - case java_awt_AlphaComposite_DST_ATOP: - { - result = "DST_ATOP"; - } - break; - case java_awt_AlphaComposite_XOR: - { - result = "XOR"; - } - break; - default: - result = "UNKNOWN"; - break; - } - const double epsilon = 0.001f; - if (fabs(_extraAlpha - 1.f) > epsilon) { - return [NSString stringWithFormat:@"%s [%1.2f]", result, _extraAlpha]; - } - return [NSString stringWithFormat:@"%s", result]; -} - -- (void)setAlphaComposite:(jint)rule { - _compState = sun_java2d_SunGraphics2D_COMP_ALPHA; - [self setRule:rule]; -} - - -- (jint)getCompositeState { - return _compState; -} - - --(void)setXORComposite:(jint)color { - _compState = sun_java2d_SunGraphics2D_COMP_XOR; - _xorPixel = color; -} - --(jint)getXorColor { - return _xorPixel; -} - -- (jfloat)getExtraAlpha { - return _extraAlpha; -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.h deleted file mode 100644 index d684f983eeb..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLContext_h_Included -#define MTLContext_h_Included - -#include "sun_java2d_pipe_BufferedContext.h" -#include "sun_java2d_metal_MTLContext_MTLContextCaps.h" - -#import <Metal/Metal.h> - -#include "MTLTexturePool.h" -#include "MTLPipelineStatesStorage.h" -#include "MTLTransform.h" -#include "MTLComposite.h" -#include "MTLPaints.h" -#include "MTLClip.h" -#include "EncoderManager.h" -#include "MTLSamplerManager.h" - -@class MTLStencilManager; - -// Constant from -// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf -#define MTL_GPU_FAMILY_MAC_TXT_SIZE 16384 - -/** - * The MTLCommandBufferWrapper class contains command buffer and - * associated resources that will be released in completion handler - * */ -@interface MTLCommandBufferWrapper : NSObject -- (id<MTLCommandBuffer>) getCommandBuffer; -- (void) onComplete; // invoked from completion handler in some pooled thread -- (void) registerPooledTexture:(MTLPooledTextureHandle *)handle; -@end - -/** - * The MTLContext class contains cached state relevant to the native - * MTL context stored within the native ctxInfo field. Each Java-level - * MTLContext object is associated with a native-level MTLContext class. - * */ -@interface MTLContext : NSObject -@property (readonly) MTLComposite * composite; -@property (readwrite, retain) MTLPaint * paint; -@property (readonly) MTLTransform * transform; -@property (readonly) MTLClip * clip; - -@property jint textureFunction; -@property jboolean vertexCacheEnabled; -@property jboolean aaEnabled; - -@property (readonly, strong) id<MTLDevice> device; -@property (strong) id<MTLCommandQueue> commandQueue; -@property (strong) id<MTLCommandQueue> blitCommandQueue; -@property (strong) id<MTLBuffer> vertexBuffer; - -@property (readonly) EncoderManager * encoderManager; -@property (readonly) MTLSamplerManager * samplerManager; -@property (readonly) MTLStencilManager * stencilManager; - -@property (strong)MTLPipelineStatesStorage* pipelineStateStorage; -@property (strong)MTLTexturePool* texturePool; - -- (MTLCommandBufferWrapper *) getCommandBufferWrapper; // creates command buffer wrapper (when doesn't exist) -- (MTLCommandBufferWrapper *) pullCommandBufferWrapper; // returns current buffer wrapper with loosing object ownership - -/** - * Fetches the MTLContext associated with the given destination surface, - * makes the context current for those surfaces, updates the destination - * viewport, and then returns a pointer to the MTLContext. - */ -+ (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst; - -- (id)initWithDevice:(id<MTLDevice>)d shadersLib:(NSString*)shadersLib; -- (void)dealloc; - -/** - * Resets the current clip state (disables both scissor and depth tests). - */ -- (void)resetClip; - -/** - * Sets the Metal scissor bounds to the provided rectangular clip bounds. - */ -- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2; - -- (const MTLScissorRect *)clipRect; - -/** - * Sets up a complex (shape) clip using the Metal stencil buffer. This - * method prepares the stencil buffer so that the clip Region spans can - * be "rendered" into it. The stencil buffer is first cleared, then the - * stencil func is setup so that when we render the clip spans, - * nothing is rendered into the color buffer, but for each pixel that would - * be rendered, a 0xFF value is placed into that location in the stencil - * buffer. With stencil test enabled, pixels will only be rendered into the - * color buffer if the corresponding value at that (x,y) location in the - * stencil buffer is equal to 0xFF. - */ -- (void)beginShapeClip:(BMTLSDOps *)dstOps; - -/** - * Finishes setting up the shape clip by resetting the stencil func - * so that future rendering operations will once again be encoded for the - * color buffer (while respecting the clip set up in the stencil buffer). - */ -- (void)endShapeClip:(BMTLSDOps *)dstOps; - -/** - * Resets all Metal compositing state (disables blending and logic - * operations). - */ -- (void)resetComposite; - -/** - * Initializes the Metal blending state. XOR mode is disabled and the - * appropriate blend functions are setup based on the AlphaComposite rule - * constant. - */ -- (void)setAlphaCompositeRule:(jint)rule extraAlpha:(jfloat)extraAlpha - flags:(jint)flags; - -/** - * Returns autorelease string with composite description (for debugging only) - */ -- (NSString*)getCompositeDescription; - -/** - * Returns autorelease string with paint description (for debugging only) - */ -- (NSString*)getPaintDescription; - -/** - * Initializes the Metal logic op state to XOR mode. Blending is disabled - * before enabling logic op mode. The XOR pixel value will be applied - * later in the MTLContext_SetColor() method. - */ -- (void)setXorComposite:(jint)xorPixel; -- (jboolean)useXORComposite; - -/** - * Resets the Metal transform state back to the identity matrix. - */ -- (void)resetTransform; - -/** - * Initializes the Metal transform state by setting the modelview transform - * using the given matrix parameters. - * - * REMIND: it may be worthwhile to add serial id to AffineTransform, so we - * could do a quick check to see if the xform has changed since - * last time... a simple object compare won't suffice... - */ -- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10 - M01:(jdouble) m01 M11:(jdouble) m11 - M02:(jdouble) m02 M12:(jdouble) m12; - -- (void)reset; -- (void)resetPaint; -- (void)setColorPaint:(int)pixel; -- (void)setGradientPaintUseMask:(jboolean)useMask - cyclic:(jboolean)cyclic - p0:(jdouble)p0 - p1:(jdouble)p1 - p3:(jdouble)p3 - pixel1:(jint)pixel1 - pixel2:(jint) pixel2; -- (void)setLinearGradientPaint:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jint)cycleMethod - numStops:(jint)numStops - p0:(jfloat)p0 - p1:(jfloat)p1 - p3:(jfloat)p3 - fractions:(jfloat *)fractions - pixels:(jint *)pixels; -- (void)setRadialGradientPaint:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jboolean)cycleMethod - numStops:(jint)numStops - m00:(jfloat)m00 - m01:(jfloat)m01 - m02:(jfloat)m02 - m10:(jfloat)m10 - m11:(jfloat)m11 - m12:(jfloat)m12 - focusX:(jfloat)focusX - fractions:(void *)fractions - pixels:(void *)pixels; -- (void)setTexturePaint:(jboolean)useMask - pSrcOps:(jlong)pSrcOps - filter:(jboolean)filter - xp0:(jdouble)xp0 - xp1:(jdouble)xp1 - xp3:(jdouble)xp3 - yp0:(jdouble)yp0 - yp1:(jdouble)yp1 - yp3:(jdouble)yp3; - -// Sets current image conversion operation (instance of MTLConvolveOp, MTLRescaleOp, MTLLookupOp). -// Used only in MTLIsoBlit (to blit image with some conversion). Pattern of usage: enableOp -> IsoBlit -> disableOp. -// TODO: Need to remove it from MTLContext and pass it as an argument for IsoBlit (because it's more -// simple and clear) --(void)setBufImgOp:(NSObject*)bufImgOp; - --(NSObject*)getBufImgOp; - -- (id<MTLCommandBuffer>)createCommandBuffer; -- (id<MTLCommandBuffer>)createBlitCommandBuffer; -@end - -/** - * See BufferedContext.java for more on these flags... - */ -#define MTLC_NO_CONTEXT_FLAGS \ - sun_java2d_pipe_BufferedContext_NO_CONTEXT_FLAGS -#define MTLC_SRC_IS_OPAQUE \ - sun_java2d_pipe_BufferedContext_SRC_IS_OPAQUE -#define MTLC_USE_MASK \ - sun_java2d_pipe_BufferedContext_USE_MASK - -#endif /* MTLContext_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.m deleted file mode 100644 index b88d60957f3..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.m +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <stdlib.h> - -#include "sun_java2d_SunGraphics2D.h" - -#include "jlong.h" -#import "MTLContext.h" -#include "MTLRenderQueue.h" -#import "MTLSamplerManager.h" -#import "MTLStencilManager.h" - - -extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *mtlsdo); - -static struct TxtVertex verts[PGRAM_VERTEX_COUNT] = { - {{-1.0, 1.0}, {0.0, 0.0}}, - {{1.0, 1.0}, {1.0, 0.0}}, - {{1.0, -1.0}, {1.0, 1.0}}, - {{1.0, -1.0}, {1.0, 1.0}}, - {{-1.0, -1.0}, {0.0, 1.0}}, - {{-1.0, 1.0}, {0.0, 0.0}} -}; - -MTLTransform* tempTransform = nil; - -@implementation MTLCommandBufferWrapper { - id<MTLCommandBuffer> _commandBuffer; - NSMutableArray * _pooledTextures; - NSLock* _lock; -} - -- (id) initWithCommandBuffer:(id<MTLCommandBuffer>)cmdBuf { - self = [super init]; - if (self) { - _commandBuffer = [cmdBuf retain]; - _pooledTextures = [[NSMutableArray alloc] init]; - _lock = [[NSLock alloc] init]; - } - return self; -} - -- (id<MTLCommandBuffer>) getCommandBuffer { - return _commandBuffer; -} - -- (void) onComplete { // invoked from completion handler in some pooled thread - [_lock lock]; - @try { - for (int c = 0; c < [_pooledTextures count]; ++c) - [[_pooledTextures objectAtIndex:c] releaseTexture]; - [_pooledTextures removeAllObjects]; - } @finally { - [_lock unlock]; - } - -} - -- (void) registerPooledTexture:(MTLPooledTextureHandle *)handle { - [_lock lock]; - @try { - [_pooledTextures addObject:handle]; - } @finally { - [_lock unlock]; - } -} - -- (void) dealloc { - [self onComplete]; - - [_pooledTextures release]; - _pooledTextures = nil; - - [_commandBuffer release]; - _commandBuffer = nil; - - [_lock release]; - _lock = nil; - [super dealloc]; -} - -@end - -@implementation MTLContext { - MTLCommandBufferWrapper * _commandBufferWrapper; - - MTLComposite * _composite; - MTLPaint * _paint; - MTLTransform * _transform; - MTLTransform * _tempTransform; - MTLClip * _clip; - NSObject* _bufImgOp; // TODO: pass as parameter of IsoBlit - - EncoderManager * _encoderManager; - MTLSamplerManager * _samplerManager; - MTLStencilManager * _stencilManager; -} - -@synthesize textureFunction, - vertexCacheEnabled, aaEnabled, device, pipelineStateStorage, - commandQueue, blitCommandQueue, vertexBuffer, - texturePool, paint=_paint, encoderManager=_encoderManager, - samplerManager=_samplerManager, stencilManager=_stencilManager; - -extern void initSamplers(id<MTLDevice> device); - -- (id)initWithDevice:(id<MTLDevice>)d shadersLib:(NSString*)shadersLib { - self = [super init]; - if (self) { - // Initialization code here. - device = d; - - pipelineStateStorage = [[MTLPipelineStatesStorage alloc] initWithDevice:device shaderLibPath:shadersLib]; - if (pipelineStateStorage == nil) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext.initWithDevice(): Failed to initialize MTLPipelineStatesStorage."); - return nil; - } - - texturePool = [[MTLTexturePool alloc] initWithDevice:device]; - - vertexBuffer = [device newBufferWithBytes:verts - length:sizeof(verts) - options:MTLResourceCPUCacheModeDefaultCache]; - - _encoderManager = [[EncoderManager alloc] init]; - [_encoderManager setContext:self]; - _samplerManager = [[MTLSamplerManager alloc] initWithDevice:device]; - _stencilManager = [[MTLStencilManager alloc] initWithDevice:device]; - _composite = [[MTLComposite alloc] init]; - _paint = [[MTLPaint alloc] init]; - _transform = [[MTLTransform alloc] init]; - _clip = [[MTLClip alloc] init]; - _bufImgOp = nil; - - _commandBufferWrapper = nil; - - // Create command queue - commandQueue = [device newCommandQueue]; - blitCommandQueue = [device newCommandQueue]; - - _tempTransform = [[MTLTransform alloc] init]; - } - return self; -} - -- (void)dealloc { - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.dealloc"); - - // TODO : Check that texturePool is completely released. - // texturePool content is released in MTLCommandBufferWrapper.onComplete() - //self.texturePool = nil; - self.vertexBuffer = nil; - self.commandQueue = nil; - self.blitCommandQueue = nil; - self.pipelineStateStorage = nil; - - if (_encoderManager != nil) { - [_encoderManager release]; - _encoderManager = nil; - } - - if (_samplerManager != nil) { - [_samplerManager release]; - _samplerManager = nil; - } - - if (_stencilManager != nil) { - [_stencilManager release]; - _stencilManager = nil; - } - - if (_composite != nil) { - [_composite release]; - _composite = nil; - } - - if (_paint != nil) { - [_paint release]; - _paint = nil; - } - - if (_transform != nil) { - [_transform release]; - _transform = nil; - } - - if (_tempTransform != nil) { - [_tempTransform release]; - _tempTransform = nil; - } - - if (_clip != nil) { - [_clip release]; - _clip = nil; - } - - [super dealloc]; -} - -- (void) reset { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLContext : reset"); - - // Add code for context state reset here -} - - - (MTLCommandBufferWrapper *) getCommandBufferWrapper { - if (_commandBufferWrapper == nil) { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLContext : commandBuffer is NULL"); - // NOTE: Command queues are thread-safe and allow multiple outstanding command buffers to be encoded simultaneously. - _commandBufferWrapper = [[MTLCommandBufferWrapper alloc] initWithCommandBuffer:[self.commandQueue commandBuffer]];// released in [layer blitTexture] - } - return _commandBufferWrapper; -} - -- (MTLCommandBufferWrapper *) pullCommandBufferWrapper { - MTLCommandBufferWrapper * result = _commandBufferWrapper; - _commandBufferWrapper = nil; - return result; -} - -+ (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst { - BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrc); - BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDst); - MTLContext *mtlc = NULL; - - if (srcOps == NULL || dstOps == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_SetSurfaces: ops are null"); - return NULL; - } - - J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLContext_SetSurfaces: bsrc=%p (tex=%p type=%d), bdst=%p (tex=%p type=%d)", srcOps, srcOps->pTexture, srcOps->drawableType, dstOps, dstOps->pTexture, dstOps->drawableType); - - if (dstOps->drawableType == MTLSD_TEXTURE) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLContext_SetSurfaces: texture cannot be used as destination"); - return NULL; - } - - if (dstOps->drawableType == MTLSD_UNDEFINED) { - // initialize the surface as an MTLSD_WINDOW - if (!MTLSD_InitMTLWindow(env, dstOps)) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLContext_SetSurfaces: could not init MTL window"); - return NULL; - } - } - - // make the context current - MTLSDOps *dstMTLOps = (MTLSDOps *)dstOps->privOps; - mtlc = dstMTLOps->configInfo->context; - - if (mtlc == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLContext_SetSurfaces: could not make context current"); - return NULL; - } - - return mtlc; -} - -- (void)resetClip { - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.resetClip"); - [_clip reset]; -} - -- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2 { - J2dTraceLn4(J2D_TRACE_INFO, "MTLContext.setClipRect: %d,%d - %d,%d", x1, y1, x2, y2); - [_clip setClipRectX1:x1 Y1:y1 X2:x2 Y2:y2]; -} - -- (void)beginShapeClip:(BMTLSDOps *)dstOps { - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.beginShapeClip"); - [_clip beginShapeClip:dstOps context:self]; - - // Store the current transform as we need to use identity transform - // for clip spans rendering - [_tempTransform copyFrom:_transform]; - [self resetTransform]; -} - -- (void)endShapeClip:(BMTLSDOps *)dstOps { - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.endShapeClip"); - [_clip endShapeClip:dstOps context:self]; - - // Reset transform for further rendering - [_transform copyFrom:_tempTransform]; -} - -- (void)resetComposite { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLContext_ResetComposite"); - [_composite reset]; -} - -- (void)setAlphaCompositeRule:(jint)rule extraAlpha:(jfloat)extraAlpha - flags:(jint)flags { - J2dTraceLn3(J2D_TRACE_INFO, "MTLContext_SetAlphaComposite: rule=%d, extraAlpha=%1.2f, flags=%d", rule, extraAlpha, flags); - - [_composite setRule:rule extraAlpha:extraAlpha]; -} - -- (NSString*)getCompositeDescription { - return [_composite getDescription]; -} - -- (NSString*)getPaintDescription { - return [_paint getDescription]; -} - -- (void)setXorComposite:(jint)xp { - J2dTraceLn1(J2D_TRACE_INFO, "MTLContext.setXorComposite: xorPixel=%08x", xp); - - [_composite setXORComposite:xp]; -} - -- (jboolean) useXORComposite { - return ([_composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR); -} - -- (void)resetTransform { - J2dTraceLn(J2D_TRACE_INFO, "MTLContext_ResetTransform"); - [_transform resetTransform]; -} - -- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10 - M01:(jdouble) m01 M11:(jdouble) m11 - M02:(jdouble) m02 M12:(jdouble) m12 { - J2dTraceLn(J2D_TRACE_INFO, "MTLContext_SetTransform"); - [_transform setTransformM00:m00 M10:m10 M01:m01 M11:m11 M02:m02 M12:m12]; -} - -- (void)resetPaint { - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.resetPaint"); - self.paint = [[[MTLPaint alloc] init] autorelease]; -} - -- (void)setColorPaint:(int)pixel { - J2dTraceLn5(J2D_TRACE_INFO, "MTLContext.setColorPaint: pixel=%08x [r=%d g=%d b=%d a=%d]", pixel, (pixel >> 16) & (0xFF), (pixel >> 8) & 0xFF, (pixel) & 0xFF, (pixel >> 24) & 0xFF); - self.paint = [[[MTLColorPaint alloc] initWithColor:pixel] autorelease]; -} - -- (void)setGradientPaintUseMask:(jboolean)useMask - cyclic:(jboolean)cyclic - p0:(jdouble)p0 - p1:(jdouble)p1 - p3:(jdouble)p3 - pixel1:(jint)pixel1 - pixel2:(jint) pixel2 -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.setGradientPaintUseMask"); - self.paint = [[[MTLGradPaint alloc] initWithUseMask:useMask - cyclic:cyclic - p0:p0 - p1:p1 - p3:p3 - pixel1:pixel1 - pixel2:pixel2] autorelease]; -} - -- (void)setLinearGradientPaint:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jint)cycleMethod - // 0 - NO_CYCLE - // 1 - REFLECT - // 2 - REPEAT - - numStops:(jint)numStops - p0:(jfloat)p0 - p1:(jfloat)p1 - p3:(jfloat)p3 - fractions:(jfloat*)fractions - pixels:(jint*)pixels -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.setLinearGradientPaint"); - self.paint = [[[MTLLinearGradPaint alloc] initWithUseMask:useMask - linear:linear - cycleMethod:cycleMethod - numStops:numStops - p0:p0 - p1:p1 - p3:p3 - fractions:fractions - pixels:pixels] autorelease]; -} - -- (void)setRadialGradientPaint:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jboolean)cycleMethod - numStops:(jint)numStops - m00:(jfloat)m00 - m01:(jfloat)m01 - m02:(jfloat)m02 - m10:(jfloat)m10 - m11:(jfloat)m11 - m12:(jfloat)m12 - focusX:(jfloat)focusX - fractions:(void *)fractions - pixels:(void *)pixels -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLContext.setRadialGradientPaint"); - self.paint = [[[MTLRadialGradPaint alloc] initWithUseMask:useMask - linear:linear - cycleMethod:cycleMethod - numStops:numStops - m00:m00 - m01:m01 - m02:m02 - m10:m10 - m11:m11 - m12:m12 - focusX:focusX - fractions:fractions - pixels:pixels] autorelease]; -} - -- (void)setTexturePaint:(jboolean)useMask - pSrcOps:(jlong)pSrcOps - filter:(jboolean)filter - xp0:(jdouble)xp0 - xp1:(jdouble)xp1 - xp3:(jdouble)xp3 - yp0:(jdouble)yp0 - yp1:(jdouble)yp1 - yp3:(jdouble)yp3 -{ - BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrcOps); - - if (srcOps == NULL || srcOps->pTexture == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_setTexturePaint: texture paint - texture is null"); - return; - } - - J2dTraceLn1(J2D_TRACE_INFO, "MTLContext.setTexturePaint [tex=%p]", srcOps->pTexture); - - self.paint = [[[MTLTexturePaint alloc] initWithUseMask:useMask - textureID:srcOps->pTexture - isOpaque:srcOps->isOpaque - filter:filter - xp0:xp0 - xp1:xp1 - xp3:xp3 - yp0:yp0 - yp1:yp1 - yp3:yp3] autorelease]; -} - -- (id<MTLCommandBuffer>)createCommandBuffer { - return [self.commandQueue commandBuffer]; -} - -/* - * This should be exclusively used only for final blit - * and present of CAMetalDrawable in MTLLayer - */ -- (id<MTLCommandBuffer>)createBlitCommandBuffer { - return [self.blitCommandQueue commandBuffer]; -} - --(void)setBufImgOp:(NSObject*)bufImgOp { - if (_bufImgOp != nil) { - [_bufImgOp release]; // context owns bufImgOp object - } - _bufImgOp = bufImgOp; -} - --(NSObject*)getBufImgOp { - return _bufImgOp; -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.h deleted file mode 100644 index 51fd9173b71..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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 MTLGlyphCache_h_Included -#define MTLGlyphCache_h_Included - -#ifdef __cplusplus -extern "C" { -#endif - -#include "jni.h" -#include "fontscalerdefs.h" -#import <Metal/Metal.h> - -typedef void (MTLFlushFunc)(); - -typedef struct _MTLCacheCellInfo MTLCacheCellInfo; - -typedef struct { - CacheCellInfo *head; - CacheCellInfo *tail; - id<MTLTexture> texture; - jint width; - jint height; - jint cellWidth; - jint cellHeight; - MTLFlushFunc *Flush; -} MTLGlyphCacheInfo; - -struct _MTLCacheCellInfo { - MTLGlyphCacheInfo *cacheInfo; - struct GlyphInfo *glyphInfo; - // next cell info in the cache's list - MTLCacheCellInfo *next; - // REMIND: find better name? - // next cell info in the glyph's cell list (next Glyph Cache Info) - MTLCacheCellInfo *nextGCI; - jint timesRendered; - jint x; - jint y; - // number of pixels from the left or right edge not considered touched - // by the glyph - jint leftOff; - jint rightOff; - jfloat tx1; - jfloat ty1; - jfloat tx2; - jfloat ty2; -}; - -MTLGlyphCacheInfo * -MTLGlyphCache_Init(jint width, jint height, - jint cellWidth, jint cellHeight, - MTLFlushFunc *func); -MTLCacheCellInfo * -MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, struct GlyphInfo *glyph); -bool -MTLGlyphCache_IsCacheFull(MTLGlyphCacheInfo *cache, GlyphInfo *glyph); -void -MTLGlyphCache_Invalidate(MTLGlyphCacheInfo *cache); -void -MTLGlyphCache_AddCellInfo(struct GlyphInfo *glyph, MTLCacheCellInfo *cellInfo); -void -MTLGlyphCache_RemoveCellInfo(struct GlyphInfo *glyph, MTLCacheCellInfo *cellInfo); -MTLCacheCellInfo * -MTLGlyphCache_GetCellInfoForCache(struct GlyphInfo *glyph, - MTLGlyphCacheInfo *cache); -JNIEXPORT void -MTLGlyphCache_RemoveAllCellInfos(struct GlyphInfo *glyph); -void -MTLGlyphCache_Free(MTLGlyphCacheInfo *cache); - -#ifdef __cplusplus -}; -#endif - -#endif /* MTLGlyphCache_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m deleted file mode 100644 index 474bdd9af65..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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. - */ - -#include <stdlib.h> -#include "jni.h" -#include "MTLGlyphCache.h" -#include "Trace.h" - -/** - * When the cache is full, we will try to reuse the cache cells that have - * been used relatively less than the others (and we will save the cells that - * have been rendered more than the threshold defined here). - */ -#define TIMES_RENDERED_THRESHOLD 5 - -/** - * Creates a new GlyphCacheInfo structure, fills in the initial values, and - * then returns a pointer to the GlyphCacheInfo record. - * - * Note that this method only sets up a data structure describing a - * rectangular region of accelerated memory, containing "virtual" cells of - * the requested size. The cell information is added lazily to the linked - * list describing the cache as new glyphs are added. Platform specific - * glyph caching code is responsible for actually creating the accelerated - * memory surface that will contain the individual glyph images. - * - * Each glyph contains a reference to a list of cell infos - one per glyph - * cache. There may be multiple glyph caches (for example, one per graphics - * adapter), so if the glyph is cached on two devices its cell list will - * consists of two elements corresponding to different glyph caches. - * - * The platform-specific glyph caching code is supposed to use - * GetCellInfoForCache method for retrieving cache infos from the glyph's list. - * - * Note that if it is guaranteed that there will be only one global glyph - * cache then it one does not have to use AccelGlyphCache_GetCellInfoForCache - * for retrieving cell info for the glyph, but instead just use the struct's - * field directly. - */ -MTLGlyphCacheInfo * -MTLGlyphCache_Init(jint width, jint height, - jint cellWidth, jint cellHeight, - MTLFlushFunc *func) -{ - MTLGlyphCacheInfo *gcinfo; - - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Init"); - - gcinfo = (MTLGlyphCacheInfo *)malloc(sizeof(MTLGlyphCacheInfo)); - if (gcinfo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLGlyphCache_Init: could not allocate MTLGlyphCacheInfo"); - return NULL; - } - - gcinfo->head = NULL; - gcinfo->tail = NULL; - gcinfo->width = width; - gcinfo->height = height; - gcinfo->cellWidth = cellWidth; - gcinfo->cellHeight = cellHeight; - gcinfo->Flush = func; - - return gcinfo; -} - -/** - * Attempts to add the provided glyph to the specified cache. If the - * operation is successful, a pointer to the newly occupied cache cell is - * stored in the glyph's cellInfo field; otherwise, its cellInfo field is - * set to NULL, indicating that the glyph's original bits should be rendered - * instead. If the cache is full, the least-recently-used glyph is - * invalidated and its cache cell is reassigned to the new glyph being added. - * - * Note that this method only ensures that a rectangular region in the - * "virtual" glyph cache is available for the glyph image. Platform specific - * glyph caching code is responsible for actually caching the glyph image - * in the associated accelerated memory surface. - * - * Returns created cell info if it was successfully created and added to the - * cache and glyph's cell lists, NULL otherwise. - */ -MTLCacheCellInfo * -MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, GlyphInfo *glyph) -{ - MTLCacheCellInfo *cellinfo = NULL; - jint w = glyph->width; - jint h = glyph->height; - - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_AddGlyph"); - - if ((glyph->width > cache->cellWidth) || - (glyph->height > cache->cellHeight)) - { - return NULL; - } - - jint x, y; - - if (cache->head == NULL) { - x = 0; - y = 0; - } else { - x = cache->tail->x + cache->cellWidth; - y = cache->tail->y; - if ((x + cache->cellWidth) > cache->width) { - x = 0; - y += cache->cellHeight; - } - } - - // create new CacheCellInfo - cellinfo = (MTLCacheCellInfo *)malloc(sizeof(MTLCacheCellInfo)); - if (cellinfo == NULL) { - J2dTraceLn(J2D_TRACE_ERROR, "could not allocate CellInfo"); - return NULL; - } - - cellinfo->cacheInfo = cache; - cellinfo->glyphInfo = glyph; - cellinfo->timesRendered = 0; - cellinfo->x = x; - cellinfo->y = y; - cellinfo->leftOff = 0; - cellinfo->rightOff = 0; - cellinfo->tx1 = (jfloat)cellinfo->x / cache->width; - cellinfo->ty1 = (jfloat)cellinfo->y / cache->height; - cellinfo->tx2 = cellinfo->tx1 + ((jfloat)w / cache->width); - cellinfo->ty2 = cellinfo->ty1 + ((jfloat)h / cache->height); - - if (cache->head == NULL) { - // initialize the head cell - cache->head = cellinfo; - } else { - // update existing tail cell - cache->tail->next = cellinfo; - } - - // add the new cell to the end of the list - cache->tail = cellinfo; - cellinfo->next = NULL; - cellinfo->nextGCI = NULL; - - // add cache cell to the glyph's cells list - MTLGlyphCache_AddCellInfo(glyph, cellinfo); - return cellinfo; -} - - -bool -MTLGlyphCache_IsCacheFull(MTLGlyphCacheInfo *cache, GlyphInfo *glyph) -{ - jint w = glyph->width; - jint h = glyph->height; - - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_IsCacheFull"); - - jint x, y; - - if (cache->head == NULL) { - return JNI_FALSE; - } else { - x = cache->tail->x + cache->cellWidth; - y = cache->tail->y; - if ((x + cache->cellWidth) > cache->width) { - x = 0; - y += cache->cellHeight; - if ((y + cache->cellHeight) > cache->height) { - return JNI_TRUE; - } - } - } - return JNI_FALSE; -} -/** - * Invalidates all cells in the cache. Note that this method does not - * attempt to compact the cache in any way; it just invalidates any cells - * that already exist. - */ -void -MTLGlyphCache_Invalidate(MTLGlyphCacheInfo *cache) -{ - MTLCacheCellInfo *cellinfo; - - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Invalidate"); - - if (cache == NULL) { - return; - } - - // flush any pending vertices that may be depending on the current - // glyph cache layout - if (cache->Flush != NULL) { - cache->Flush(); - } - - cellinfo = cache->head; - while (cellinfo != NULL) { - if (cellinfo->glyphInfo != NULL) { - // if the cell is occupied, notify the base glyph that its - // cached version for this cache is about to be invalidated - MTLGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo); - } - cellinfo = cellinfo->next; - } -} - -/** - * Invalidates and frees all cells and the cache itself. The "cache" pointer - * becomes invalid after this function returns. - */ -void -MTLGlyphCache_Free(MTLGlyphCacheInfo *cache) -{ - MTLCacheCellInfo *cellinfo; - - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Free"); - - if (cache == NULL) { - return; - } - - // flush any pending vertices that may be depending on the current - // glyph cache - if (cache->Flush != NULL) { - cache->Flush(); - } - - while (cache->head != NULL) { - cellinfo = cache->head; - if (cellinfo->glyphInfo != NULL) { - // if the cell is occupied, notify the base glyph that its - // cached version for this cache is about to be invalidated - MTLGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo); - } - cache->head = cellinfo->next; - free(cellinfo); - } - free(cache); -} - -/** - * Add cell info to the head of the glyph's list of cached cells. - */ -void -MTLGlyphCache_AddCellInfo(GlyphInfo *glyph, MTLCacheCellInfo *cellInfo) -{ - // assert (glyph != NULL && cellInfo != NULL) - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_AddCellInfo"); - J2dTraceLn2(J2D_TRACE_VERBOSE, " glyph 0x%x: adding cell 0x%x to the list", - glyph, cellInfo); - - cellInfo->glyphInfo = glyph; - cellInfo->nextGCI = glyph->cellInfo; - glyph->cellInfo = cellInfo; - glyph->managed = MANAGED_GLYPH; -} - -/** - * Removes cell info from the glyph's list of cached cells. - */ -void -MTLGlyphCache_RemoveCellInfo(GlyphInfo *glyph, MTLCacheCellInfo *cellInfo) -{ - MTLCacheCellInfo *currCellInfo = glyph->cellInfo; - MTLCacheCellInfo *prevInfo = NULL; - // assert (glyph!= NULL && glyph->cellInfo != NULL && cellInfo != NULL) - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_RemoveCellInfo"); - do { - if (currCellInfo == cellInfo) { - J2dTraceLn2(J2D_TRACE_VERBOSE, - " glyph 0x%x: removing cell 0x%x from glyph's list", - glyph, currCellInfo); - if (prevInfo == NULL) { // it's the head, chop-chop - glyph->cellInfo = currCellInfo->nextGCI; - } else { - prevInfo->nextGCI = currCellInfo->nextGCI; - } - currCellInfo->glyphInfo = NULL; - currCellInfo->nextGCI = NULL; - return; - } - prevInfo = currCellInfo; - currCellInfo = currCellInfo->nextGCI; - } while (currCellInfo != NULL); - J2dTraceLn2(J2D_TRACE_WARNING, "MTLGlyphCache_RemoveCellInfo: "\ - "no cell 0x%x in glyph 0x%x's cell list", - cellInfo, glyph); -} - -/** - * Removes cell info from the glyph's list of cached cells. - */ -JNIEXPORT void -MTLGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph) -{ - MTLCacheCellInfo *currCell, *prevCell; - - J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_RemoveAllCellInfos"); - - if (glyph == NULL || glyph->cellInfo == NULL) { - return; - } - - // invalidate all of this glyph's accelerated cache cells - currCell = glyph->cellInfo; - do { - currCell->glyphInfo = NULL; - prevCell = currCell; - currCell = currCell->nextGCI; - prevCell->nextGCI = NULL; - } while (currCell != NULL); - - glyph->cellInfo = NULL; -} - -/** - * Returns cell info associated with particular cache from the glyph's list of - * cached cells. - */ -MTLCacheCellInfo * -MTLGlyphCache_GetCellInfoForCache(GlyphInfo *glyph, MTLGlyphCacheInfo *cache) -{ - // assert (glyph != NULL && cache != NULL) - J2dTraceLn(J2D_TRACE_VERBOSE2, "MTLGlyphCache_GetCellInfoForCache"); - - if (glyph->cellInfo != NULL) { - MTLCacheCellInfo *cellInfo = glyph->cellInfo; - do { - if (cellInfo->cacheInfo == cache) { - J2dTraceLn3(J2D_TRACE_VERBOSE2, - " glyph 0x%x: found cell 0x%x for cache 0x%x", - glyph, cellInfo, cache); - return cellInfo; - } - cellInfo = cellInfo->nextGCI; - } while (cellInfo != NULL); - } - J2dTraceLn2(J2D_TRACE_VERBOSE2, " glyph 0x%x: no cell for cache 0x%x", - glyph, cache); - return NULL; -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.h deleted file mode 100644 index f86b59d14b6..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLGraphicsConfig_h_Included -#define MTLGraphicsConfig_h_Included - -#import "JNIUtilities.h" -#import "MTLSurfaceDataBase.h" -#import "MTLContext.h" -#import <Cocoa/Cocoa.h> -#import <Metal/Metal.h> - - -@interface MTLGraphicsConfigUtil : NSObject {} -+ (void) _getMTLConfigInfo: (NSMutableArray *)argValue; -@end - -/** - * The MTLGraphicsConfigInfo structure contains information specific to a - * given MTLGraphicsConfig (pixel format). - * MTLContext *context; - * The context associated with this MTLGraphicsConfig. - */ -typedef struct _MTLGraphicsConfigInfo { - MTLContext *context; -} MTLGraphicsConfigInfo; - -#endif /* MTLGraphicsConfig_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m deleted file mode 100644 index b53d7878eb6..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#import "sun_java2d_metal_MTLGraphicsConfig.h" - -#import "MTLGraphicsConfig.h" -#import "ThreadUtilities.h" -#import "awt.h" - -/** - * Disposes all memory and resources associated with the given - * MTLGraphicsConfigInfo (including its native MTLContext data). - */ -void -MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLGC_DestroyMTLGraphicsConfig"); - - MTLGraphicsConfigInfo *mtlinfo = - (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); - if (mtlinfo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLGC_DestroyMTLGraphicsConfig: info is null"); - return; - } - - MTLContext *mtlc = (MTLContext*)mtlinfo->context; - if (mtlc != NULL) { - [mtlinfo->context release]; - mtlinfo->context = nil; - } - free(mtlinfo); -} - -JNIEXPORT jboolean JNICALL -Java_sun_java2d_metal_MTLGraphicsConfig_isMetalFrameworkAvailable - (JNIEnv *env, jclass mtlgc) -{ - jboolean metalSupported = JNI_FALSE; - - // It is guranteed that metal supported GPU is available macOS 10.14 onwards - if (@available(macOS 10.14, *)) { - metalSupported = JNI_TRUE; - } - - J2dRlsTraceLn1(J2D_TRACE_INFO, "MTLGraphicsConfig_isMetalFrameworkAvailable : %d", metalSupported); - - return metalSupported; -} - -JNIEXPORT jboolean JNICALL -Java_sun_java2d_metal_MTLGraphicsConfig_tryLoadMetalLibrary - (JNIEnv *env, jclass mtlgc, jint displayID, jstring shadersLibName) -{ - __block jboolean ret = JNI_FALSE; - -JNI_COCOA_ENTER(env); - - __block NSString* path = NormalizedPathNSStringFromJavaString(env, shadersLibName); - - [ThreadUtilities performOnMainThreadWaiting:YES block:^() { - - id<MTLDevice> device = CGDirectDisplayCopyCurrentMetalDevice(displayID); - if (device != nil) { - NSError* error = nil; - id<MTLLibrary> lib = [device newLibraryWithFile:path error:&error]; - if (lib != nil) { - ret = JNI_TRUE; - } else { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_tryLoadMetalLibrary - Failed to load Metal shader library."); - } - } else { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_tryLoadMetalLibrary - Failed to create MTLDevice."); - } - }]; - -JNI_COCOA_EXIT(env); - return ret; -} - -/** - * Determines whether the Metal pipeline can be used for a given screen number and - * shader library path. A MTLContext is created and the native MTLGraphicsConfigInfo - * structure is initialized for this context. A pointer to this structure is - * returned as a jlong. - * If initialization fails at any point, zero is returned, indicating that Metal pipeline - * cannot be used for this GraphicsConfig (we should fallback on an existing 2D pipeline). - */ -JNIEXPORT jlong JNICALL -Java_sun_java2d_metal_MTLGraphicsConfig_getMTLConfigInfo - (JNIEnv *env, jclass mtlgc, jint displayID, jstring mtlShadersLib) -{ - __block MTLContext* mtlc = nil; - __block MTLGraphicsConfigInfo* mtlinfo = nil; - -JNI_COCOA_ENTER(env); - - __block NSString* path = NormalizedPathNSStringFromJavaString(env, mtlShadersLib); - - [ThreadUtilities performOnMainThreadWaiting:YES block:^() { - - mtlc = [[MTLContext alloc] initWithDevice:CGDirectDisplayCopyCurrentMetalDevice(displayID) - shadersLib:path]; - if (mtlc != 0L) { - // create the MTLGraphicsConfigInfo record for this context - mtlinfo = (MTLGraphicsConfigInfo *)malloc(sizeof(MTLGraphicsConfigInfo)); - if (mtlinfo != NULL) { - memset(mtlinfo, 0, sizeof(MTLGraphicsConfigInfo)); - mtlinfo->context = mtlc; - } else { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: could not allocate memory for mtlinfo"); - [mtlc release]; - mtlc = nil; - } - } else { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: could not initialze MTLContext."); - } - }]; - -JNI_COCOA_EXIT(env); - - return ptr_to_jlong(mtlinfo); -} - -JNIEXPORT jint JNICALL -Java_sun_java2d_metal_MTLGraphicsConfig_nativeGetMaxTextureSize - (JNIEnv *env, jclass mtlgc) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_nativeGetMaxTextureSize"); - - return (jint)MTL_GPU_FAMILY_MAC_TXT_SIZE; -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.h deleted file mode 100644 index dceac2ad433..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLLayer_h_Included -#define MTLLayer_h_Included -#import <Metal/Metal.h> -#import <QuartzCore/CAMetalLayer.h> -#include <CoreVideo/CVDisplayLink.h> -#import "common.h" - -@interface MTLLayer : CAMetalLayer -{ -@private - jobject javaLayer; - - // intermediate buffer, used the RQ lock to synchronize - MTLContext* ctx; - float bufferWidth; - float bufferHeight; - id<MTLTexture> buffer; - int nextDrawableCount; - int topInset; - int leftInset; - CVDisplayLinkRef displayLink; -} - -@property (nonatomic) jobject javaLayer; -@property (readwrite, assign) MTLContext* ctx; -@property (readwrite, assign) float bufferWidth; -@property (readwrite, assign) float bufferHeight; -@property (readwrite, assign) id<MTLTexture> buffer; -@property (readwrite, assign) int nextDrawableCount; -@property (readwrite, assign) int topInset; -@property (readwrite, assign) int leftInset; -@property (readwrite, assign) CVDisplayLinkRef displayLink; - -- (id) initWithJavaLayer:(jobject)layer; - -- (void) blitTexture; -- (void) fillParallelogramCtxX:(jfloat)x - Y:(jfloat)y - DX1:(jfloat)dx1 - DY1:(jfloat)dy1 - DX2:(jfloat)dx2 - DY2:(jfloat)dy2; -- (void) blitCallback; -- (void) display; -- (void) redraw; -- (void) startDisplayLink; -- (void) stopDisplayLink; -@end - -#endif /* MTLLayer_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.m deleted file mode 100644 index ecd4b67509f..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.m +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#import "MTLGraphicsConfig.h" -#import "MTLLayer.h" -#import "ThreadUtilities.h" -#import "LWCToolkit.h" -#import "MTLSurfaceData.h" -#import "JNIUtilities.h" - -@implementation MTLLayer - - -@synthesize javaLayer; -@synthesize ctx; -@synthesize bufferWidth; -@synthesize bufferHeight; -@synthesize buffer; -@synthesize topInset; -@synthesize leftInset; -@synthesize nextDrawableCount; -@synthesize displayLink; - -- (id) initWithJavaLayer:(jobject)layer -{ - AWT_ASSERT_APPKIT_THREAD; - // Initialize ourselves - self = [super init]; - if (self == nil) return self; - - self.javaLayer = layer; - - self.contentsGravity = kCAGravityTopLeft; - - //Disable CALayer's default animation - NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys: - [NSNull null], @"anchorPoint", - [NSNull null], @"bounds", - [NSNull null], @"contents", - [NSNull null], @"contentsScale", - [NSNull null], @"onOrderIn", - [NSNull null], @"onOrderOut", - [NSNull null], @"position", - [NSNull null], @"sublayers", - nil]; - self.actions = actions; - [actions release]; - self.topInset = 0; - self.leftInset = 0; - self.framebufferOnly = NO; - self.nextDrawableCount = 0; - self.opaque = FALSE; - CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); - CVDisplayLinkSetOutputCallback(displayLink, &displayLinkCallback, (__bridge void*)self); - return self; -} - -- (void) blitTexture { - if (self.ctx == NULL || self.javaLayer == NULL || self.buffer == nil || self.ctx.device == nil) { - J2dTraceLn4(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: uninitialized (mtlc=%p, javaLayer=%p, buffer=%p, devide=%p)", self.ctx, self.javaLayer, self.buffer, ctx.device); - [self stopDisplayLink]; - return; - } - - if (self.nextDrawableCount != 0) { - return; - } - @autoreleasepool { - if ((self.buffer.width == 0) || (self.buffer.height == 0)) { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: cannot create drawable of size 0"); - [self stopDisplayLink]; - return; - } - - NSUInteger src_x = self.leftInset * self.contentsScale; - NSUInteger src_y = self.topInset * self.contentsScale; - NSUInteger src_w = self.buffer.width - src_x; - NSUInteger src_h = self.buffer.height - src_y; - - if (src_h <= 0 || src_w <= 0) { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: Invalid src width or height."); - [self stopDisplayLink]; - return; - } - - id<MTLCommandBuffer> commandBuf = [self.ctx createBlitCommandBuffer]; - if (commandBuf == nil) { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: commandBuf is null"); - [self stopDisplayLink]; - return; - } - id<CAMetalDrawable> mtlDrawable = [self nextDrawable]; - if (mtlDrawable == nil) { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: nextDrawable is null)"); - [self stopDisplayLink]; - return; - } - self.nextDrawableCount++; - - id <MTLBlitCommandEncoder> blitEncoder = [commandBuf blitCommandEncoder]; - - [blitEncoder - copyFromTexture:self.buffer sourceSlice:0 sourceLevel:0 - sourceOrigin:MTLOriginMake(src_x, src_y, 0) - sourceSize:MTLSizeMake(src_w, src_h, 1) - toTexture:mtlDrawable.texture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(0, 0, 0)]; - [blitEncoder endEncoding]; - - [commandBuf presentDrawable:mtlDrawable]; - [commandBuf addCompletedHandler:^(id <MTLCommandBuffer> commandBuf) { - self.nextDrawableCount--; - }]; - - [commandBuf commit]; - [self stopDisplayLink]; - } -} - -- (void) dealloc { - JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - (*env)->DeleteWeakGlobalRef(env, self.javaLayer); - self.javaLayer = nil; - [self stopDisplayLink]; - CVDisplayLinkRelease(self.displayLink); - self.displayLink = nil; - [super dealloc]; -} - -- (void) blitCallback { - - JNIEnv *env = [ThreadUtilities getJNIEnv]; - DECLARE_CLASS(jc_JavaLayer, "sun/java2d/metal/MTLLayer"); - DECLARE_METHOD(jm_drawInMTLContext, jc_JavaLayer, "drawInMTLContext", "()V"); - - jobject javaLayerLocalRef = (*env)->NewLocalRef(env, self.javaLayer); - if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) { - return; - } - - (*env)->CallVoidMethod(env, javaLayerLocalRef, jm_drawInMTLContext); - CHECK_EXCEPTION(); - (*env)->DeleteLocalRef(env, javaLayerLocalRef); -} - -- (void) display { - AWT_ASSERT_APPKIT_THREAD; - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_display() called"); - [self blitCallback]; - [super display]; -} - -- (void) redraw { - AWT_ASSERT_APPKIT_THREAD; - [self setNeedsDisplay]; -} - -- (void) startDisplayLink { - if (!CVDisplayLinkIsRunning(self.displayLink)) - CVDisplayLinkStart(self.displayLink); -} - -- (void) stopDisplayLink { - if (CVDisplayLinkIsRunning(self.displayLink)) - CVDisplayLinkStop(self.displayLink); -} - -CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) -{ - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_displayLinkCallback() called"); - @autoreleasepool { - MTLLayer *layer = (__bridge MTLLayer *)displayLinkContext; - [layer performSelectorOnMainThread:@selector(redraw) withObject:nil waitUntilDone:NO]; - } - return kCVReturnSuccess; -} -@end - -/* - * Class: sun_java2d_metal_MTLLayer - * Method: nativeCreateLayer - * Signature: ()J - */ -JNIEXPORT jlong JNICALL -Java_sun_java2d_metal_MTLLayer_nativeCreateLayer -(JNIEnv *env, jobject obj) -{ - __block MTLLayer *layer = nil; - -JNI_COCOA_ENTER(env); - - jobject javaLayer = (*env)->NewWeakGlobalRef(env, obj); - - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - AWT_ASSERT_APPKIT_THREAD; - - layer = [[MTLLayer alloc] initWithJavaLayer: javaLayer]; - }]; - -JNI_COCOA_EXIT(env); - - return ptr_to_jlong(layer); -} - -// Must be called under the RQ lock. -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLLayer_validate -(JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData) -{ - MTLLayer *layer = OBJC(layerPtr); - - if (surfaceData != NULL) { - BMTLSDOps *bmtlsdo = (BMTLSDOps*) SurfaceData_GetOps(env, surfaceData); - layer.bufferWidth = bmtlsdo->width; - layer.bufferHeight = bmtlsdo->width; - layer.buffer = bmtlsdo->pTexture; - layer.ctx = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->context; - layer.device = layer.ctx.device; - layer.pixelFormat = MTLPixelFormatBGRA8Unorm; - layer.drawableSize = - CGSizeMake(layer.buffer.width, - layer.buffer.height); - [layer startDisplayLink]; - } else { - layer.ctx = NULL; - [layer stopDisplayLink]; - } -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLLayer_nativeSetScale -(JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale) -{ - JNI_COCOA_ENTER(env); - MTLLayer *layer = jlong_to_ptr(layerPtr); - // We always call all setXX methods asynchronously, exception is only in - // this method where we need to change native texture size and layer's scale - // in one call on appkit, otherwise we'll get window's contents blinking, - // during screen-2-screen moving. - [ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){ - layer.contentsScale = scale; - }]; - JNI_COCOA_EXIT(env); -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLLayer_nativeSetInsets -(JNIEnv *env, jclass cls, jlong layerPtr, jint top, jint left) -{ - MTLLayer *layer = jlong_to_ptr(layerPtr); - layer.topInset = top; - layer.leftInset = left; -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLLayer_blitTexture -(JNIEnv *env, jclass cls, jlong layerPtr) -{ - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blitTexture"); - MTLLayer *layer = jlong_to_ptr(layerPtr); - MTLContext * ctx = layer.ctx; - if (layer == NULL || ctx == NULL) { - J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blit : Layer or Context is null"); - [layer stopDisplayLink]; - return; - } - - [layer blitTexture]; -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.h deleted file mode 100644 index 201bbb8115a..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLMaskBlit_h_Included -#define MTLMaskBlit_h_Included - -#include "MTLContext.h" - -void MTLMaskBlit_MaskBlit(JNIEnv *env, MTLContext *mtlc, BMTLSDOps * dstOps, - jint dstx, jint dsty, - jint width, jint height, - void *pPixels); - -#endif /* MTLMaskBlit_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.m deleted file mode 100644 index d23975ff4b5..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.m +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <stdlib.h> -#include <jlong.h> - -#include "MTLMaskBlit.h" -#include "MTLRenderQueue.h" -#include "MTLBlitLoops.h" - -/** - * REMIND: This method assumes that the dimensions of the incoming pixel - * array are less than or equal to the cached blit texture tile; - * these are rather fragile assumptions, and should be cleaned up... - */ -void -MTLMaskBlit_MaskBlit(JNIEnv *env, MTLContext *mtlc, BMTLSDOps * dstOps, - jint dstx, jint dsty, - jint width, jint height, - void *pPixels) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLMaskBlit_MaskBlit"); - - if (width <= 0 || height <= 0) { - J2dTraceLn(J2D_TRACE_WARNING, "MTLMaskBlit_MaskBlit: invalid dimensions"); - return; - } - - RETURN_IF_NULL(pPixels); - RETURN_IF_NULL(mtlc); - - MTLPooledTextureHandle * texHandle = [mtlc.texturePool - getTexture:width - height:height - format:MTLPixelFormatBGRA8Unorm]; - if (texHandle == nil) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLMaskBlit_MaskBlit: can't obtain temporary texture object from pool"); - return; - } - [[mtlc getCommandBufferWrapper] registerPooledTexture:texHandle]; - - id<MTLTexture> texBuff = texHandle.texture; - MTLRegion region = MTLRegionMake2D(0, 0, width, height); - [texBuff replaceRegion:region mipmapLevel:0 withBytes:pPixels bytesPerRow:4*width]; - - drawTex2Tex(mtlc, texBuff, dstOps->pTexture, JNI_FALSE, dstOps->isOpaque, 0, - 0, 0, width, height, dstx, dsty, dstx + width, dsty + height); -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.h deleted file mode 100644 index 3e74e048941..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLMaskFill_h_Included -#define MTLMaskFill_h_Included - -#include "MTLContext.h" - -void MTLMaskFill_MaskFill(MTLContext *mtlc, BMTLSDOps * dstOps, - jint x, jint y, jint w, jint h, - jint maskoff, jint maskscan, jint masklen, - unsigned char *pMask); - -#endif /* MTLMaskFill_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.m deleted file mode 100644 index 89fad174c1e..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.m +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "sun_java2d_metal_MTLMaskFill.h" - -#include "MTLMaskFill.h" -#include "MTLRenderQueue.h" -#include "MTLVertexCache.h" - -/** - * In case of Metal we use shader for texture mapping. - * - * Descriptions of the many variables used in this method: - * x,y - upper left corner of the tile destination - * w,h - width/height of the mask tile - * x0 - placekeeper for the original destination x location - * tw,th - width/height of the actual texture tile in pixels - * sx1,sy1 - upper left corner of the mask tile source region - * sx2,sy2 - lower left corner of the mask tile source region - * sx,sy - "current" upper left corner of the mask tile region of interest - */ -void -MTLMaskFill_MaskFill(MTLContext *mtlc, BMTLSDOps * dstOps, - jint x, jint y, jint w, jint h, - jint maskoff, jint maskscan, jint masklen, - unsigned char *pMask) -{ - J2dTraceLn5(J2D_TRACE_INFO, "MTLMaskFill_MaskFill (x=%d y=%d w=%d h=%d pMask=%p)", x, y, w, h, dstOps->pTexture); - jint tw, th, x0; - jint sx1, sy1, sx2, sy2; - jint sx, sy, sw, sh; - - x0 = x; - tw = MTLVC_MASK_CACHE_TILE_WIDTH; - th = MTLVC_MASK_CACHE_TILE_HEIGHT; - sx1 = maskoff % maskscan; - sy1 = maskoff / maskscan; - sx2 = sx1 + w; - sy2 = sy1 + h; - - - for (sy = sy1; sy < sy2; sy += th, y += th) { - x = x0; - sh = ((sy + th) > sy2) ? (sy2 - sy) : th; - - for (sx = sx1; sx < sx2; sx += tw, x += tw) { - sw = ((sx + tw) > sx2) ? (sx2 - sx) : tw; - MTLVertexCache_AddMaskQuad(mtlc, - sx, sy, x, y, sw, sh, - maskscan, pMask, dstOps); - } - } -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLMaskFill_maskFill - (JNIEnv *env, jobject self, - jint x, jint y, jint w, jint h, - jint maskoff, jint maskscan, jint masklen, - jbyteArray maskArray) -{ - MTLContext *mtlc = MTLRenderQueue_GetCurrentContext(); - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - unsigned char *mask; - - J2dTraceLn(J2D_TRACE_ERROR, "MTLMaskFill_maskFill"); - - if (maskArray != NULL) { - mask = (unsigned char *) - (*env)->GetPrimitiveArrayCritical(env, maskArray, NULL); - } else { - mask = NULL; - } - - MTLMaskFill_MaskFill(mtlc, dstOps, - x, y, w, h, - maskoff, maskscan, masklen, mask); - if (mtlc != NULL) { - RESET_PREVIOUS_OP(); - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - } - - if (mask != NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT); - } -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.h deleted file mode 100644 index 20ba80a9949..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLPaints_h_Included -#define MTLPaints_h_Included - -#import <Metal/Metal.h> -#include "RenderOptions.h" - -#define sun_java2d_SunGraphics2D_PAINT_UNDEFINED -1 - -@class MTLContext; -@class MTLComposite; -@class MTLClip; -@class MTLPipelineStatesStorage; - -/** - * The MTLPaint class represents paint mode (color, gradient etc.) - */ - -@interface MTLPaint : NSObject - -- (id)initWithState:(jint)state; -- (BOOL)isEqual:(MTLPaint *)other; // used to compare requested with cached -- (NSString *)getDescription; - -// For the current paint mode and passed composite (and flags): -// 1. Selects vertex+fragment shader (and corresponding pipelineDesc) and set pipelineState -// 2. Prepares corresponding buffers of vertex and fragment shaders - -- (void)setPipelineState:(id <MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage; - - -- (void)setXorModePipelineState:(id <MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage; -@end - -@interface MTLColorPaint : MTLPaint -- (id)initWithColor:(jint)color; -@property (nonatomic, readonly) jint color; -@end - -@interface MTLBaseGradPaint : MTLPaint -- (id)initWithState:(jint)state - mask:(jboolean)useMask - cyclic:(jboolean)cyclic; -@end - -@interface MTLGradPaint : MTLBaseGradPaint - -- (id)initWithUseMask:(jboolean)useMask - cyclic:(jboolean)cyclic - p0:(jdouble)p0 - p1:(jdouble)p1 - p3:(jdouble)p3 - pixel1:(jint)pixel1 - pixel2:(jint)pixel2; -@end - -@interface MTLBaseMultiGradPaint : MTLBaseGradPaint - -- (id)initWithState:(jint)state - mask:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jboolean)cycleMethod - numStops:(jint)numStops - fractions:(jfloat *)fractions - pixels:(jint *)pixels; -@end - -@interface MTLLinearGradPaint : MTLBaseMultiGradPaint - -- (id)initWithUseMask:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jboolean)cycleMethod - numStops:(jint)numStops - p0:(jfloat)p0 - p1:(jfloat)p1 - p3:(jfloat)p3 - fractions:(jfloat *)fractions - pixels:(jint *)pixels; -@end - -@interface MTLRadialGradPaint : MTLBaseMultiGradPaint - -- (id)initWithUseMask:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jint)cycleMethod - numStops:(jint)numStops - m00:(jfloat)m00 - m01:(jfloat)m01 - m02:(jfloat)m02 - m10:(jfloat)m10 - m11:(jfloat)m11 - m12:(jfloat)m12 - focusX:(jfloat)focusX - fractions:(void *)fractions - pixels:(void *)pixels; -@end - -@interface MTLTexturePaint : MTLPaint - -- (id)initWithUseMask:(jboolean)useMask - textureID:(id <MTLTexture>)textureID - isOpaque:(jboolean)isOpaque - filter:(jboolean)filter - xp0:(jdouble)xp0 - xp1:(jdouble)xp1 - xp3:(jdouble)xp3 - yp0:(jdouble)yp0 - yp1:(jdouble)yp1 - yp3:(jdouble)yp3; -@end - -#endif /* MTLPaints_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m deleted file mode 100644 index 8bff3c4c2fb..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m +++ /dev/null @@ -1,993 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "MTLPaints.h" -#include "MTLClip.h" -#include "common.h" - -#include "sun_java2d_SunGraphics2D.h" -#include "sun_java2d_pipe_BufferedPaints.h" -#import "MTLComposite.h" -#import "MTLBufImgOps.h" -#include "MTLRenderQueue.h" - -#define RGBA_TO_V4(c) \ -{ \ - (((c) >> 16) & (0xFF))/255.0f, \ - (((c) >> 8) & 0xFF)/255.0f, \ - ((c) & 0xFF)/255.0f, \ - (((c) >> 24) & 0xFF)/255.0f \ -} - -#define FLOAT_ARR_TO_V4(p) \ -{ \ - p[0], \ - p[1], \ - p[2], \ - p[3] \ -} - -static MTLRenderPipelineDescriptor * templateRenderPipelineDesc = nil; -static MTLRenderPipelineDescriptor * templateTexturePipelineDesc = nil; -static MTLRenderPipelineDescriptor * templateAATexturePipelineDesc = nil; -static MTLRenderPipelineDescriptor * templateLCDPipelineDesc = nil; -static MTLRenderPipelineDescriptor * templateAAPipelineDesc = nil; -static void -setTxtUniforms(MTLContext *mtlc, int color, id <MTLRenderCommandEncoder> encoder, int interpolation, bool repeat, - jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, const SurfaceRasterFlags *dstFlags, int mode); - -static void initTemplatePipelineDescriptors() { - if (templateRenderPipelineDesc != nil && templateTexturePipelineDesc != nil && - templateAATexturePipelineDesc != nil && templateLCDPipelineDesc != nil && - templateAAPipelineDesc != nil) - return; - - MTLVertexDescriptor *vertDesc = [[MTLVertexDescriptor new] autorelease]; - vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat2; - vertDesc.attributes[VertexAttributePosition].offset = 0; - vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer; - vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct Vertex); - vertDesc.layouts[MeshVertexBuffer].stepRate = 1; - vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex; - - templateRenderPipelineDesc = [MTLRenderPipelineDescriptor new]; - templateRenderPipelineDesc.sampleCount = 1; - templateRenderPipelineDesc.vertexDescriptor = vertDesc; - templateRenderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; - templateRenderPipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - templateRenderPipelineDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; - templateRenderPipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne; - templateRenderPipelineDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; - templateRenderPipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - templateRenderPipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - templateRenderPipelineDesc.label = @"template_render"; - - templateTexturePipelineDesc = [templateRenderPipelineDesc copy]; - templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2; - templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 2*sizeof(float); - templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer; - templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stride = sizeof(struct TxtVertex); - templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepRate = 1; - templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex; - templateTexturePipelineDesc.label = @"template_texture"; - - templateAATexturePipelineDesc = [templateTexturePipelineDesc copy]; - templateAATexturePipelineDesc.label = @"template_aa_texture"; - - templateLCDPipelineDesc = [MTLRenderPipelineDescriptor new]; - templateLCDPipelineDesc.sampleCount = 1; - templateLCDPipelineDesc.vertexDescriptor = vertDesc; - templateLCDPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; - templateLCDPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2; - templateLCDPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 2*sizeof(float); - templateLCDPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer; - templateLCDPipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stride = sizeof(struct TxtVertex); - templateLCDPipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepRate = 1; - templateLCDPipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex; - templateLCDPipelineDesc.label = @"template_lcd"; - - vertDesc = [[MTLVertexDescriptor new] autorelease]; - vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat2; - vertDesc.attributes[VertexAttributePosition].offset = 0; - vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer; - vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct AAVertex); - vertDesc.layouts[MeshVertexBuffer].stepRate = 1; - vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex; - - templateAAPipelineDesc = [MTLRenderPipelineDescriptor new]; - templateAAPipelineDesc.sampleCount = 1; - templateAAPipelineDesc.vertexDescriptor = vertDesc; - templateAAPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; - templateAAPipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - templateAAPipelineDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; - templateAAPipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne; - templateAAPipelineDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; - templateAAPipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - templateAAPipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - templateAAPipelineDesc.colorAttachments[0].blendingEnabled = YES; - templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2; - templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 2*sizeof(float); - templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer; - templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeITexPos].format = MTLVertexFormatFloat2; - templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeITexPos].offset = 4*sizeof(float); - templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeITexPos].bufferIndex = MeshVertexBuffer; - templateAAPipelineDesc.label = @"template_aa"; -} - - -@implementation MTLColorPaint { -// color-mode -jint _color; -} -- (id)initWithColor:(jint)color { - self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR]; - - if (self) { - _color = color; - } - return self; -} - -- (jint)color { - return _color; -} - -- (BOOL)isEqual:(MTLColorPaint *)other { - if (other == self) - return YES; - if (!other || ![[other class] isEqual:[self class]]) - return NO; - - return _color == other->_color; -} - -- (NSUInteger)hash { - NSUInteger h = [super hash]; - h = h*31 + _color; - return h; -} - -- (NSString *)description { - return [NSString stringWithFormat: - @"[r=%d g=%d b=%d a=%d]", - (_color >> 16) & (0xFF), - (_color >> 8) & 0xFF, - (_color) & 0xFF, - (_color >> 24) & 0xFF]; -} - -- (void)setPipelineState:(id<MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - - MTLRenderPipelineDescriptor *rpDesc = nil; - - NSString *vertShader = @"vert_col"; - NSString *fragShader = @"frag_col"; - - if (renderOptions->isTexture) { - vertShader = @"vert_txt"; - fragShader = @"frag_txt"; - rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - if (renderOptions->isAA) { - fragShader = @"aa_frag_txt"; - rpDesc = [[templateAATexturePipelineDesc copy] autorelease]; - } - if (renderOptions->isText) { - fragShader = @"frag_text"; - } - if (renderOptions->isLCD) { - vertShader = @"vert_txt_lcd"; - fragShader = @"lcd_color"; - rpDesc = [[templateLCDPipelineDesc copy] autorelease]; - } - setTxtUniforms(mtlc, _color, encoder, - renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], &renderOptions->srcFlags, - &renderOptions->dstFlags, 1); - } else if (renderOptions->isAAShader) { - vertShader = @"vert_col_aa"; - fragShader = @"frag_col_aa"; - rpDesc = [[templateAAPipelineDesc copy] autorelease]; - } else { - rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - } - - struct FrameUniforms uf = {RGBA_TO_V4(_color)}; - [encoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} - -- (void)setXorModePipelineState:(id<MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - NSString * vertShader = @"vert_col_xorMode"; - NSString * fragShader = @"frag_col_xorMode"; - MTLRenderPipelineDescriptor * rpDesc = nil; - jint xorColor = (jint) [mtlc.composite getXorColor]; - // Calculate _color ^ xorColor for RGB components - // This color gets XORed with destination framebuffer pixel color - const int col = _color ^ xorColor; - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - - if (renderOptions->isTexture) { - vertShader = @"vert_txt_xorMode"; - fragShader = @"frag_txt_xorMode"; - rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - - setTxtUniforms(mtlc, col, encoder, - renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, &renderOptions->dstFlags, 1); - [encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex:0]; - - [encoder setFragmentTexture:dstOps->pTexture atIndex:1]; - } else { - struct FrameUniforms uf = {RGBA_TO_V4(col)}; - rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - - [encoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - [encoder setFragmentTexture:dstOps->pTexture atIndex:0]; - } - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} -@end - -@implementation MTLBaseGradPaint { - jboolean _useMask; -@protected - jint _cyclic; -} - -- (id)initWithState:(jint)state mask:(jboolean)useMask cyclic:(jboolean)cyclic { - self = [super initWithState:state]; - - if (self) { - _useMask = useMask; - _cyclic = cyclic; - } - return self; -} - -- (BOOL)isEqual:(MTLBaseGradPaint *)other { - if (other == self) - return YES; - if (!other || ![[other class] isEqual:[self class]]) - return NO; - - return [super isEqual:self] && _cyclic == other->_cyclic && _useMask == other->_useMask; -} - -- (NSUInteger)hash { - NSUInteger h = [super hash]; - h = h*31 + _cyclic; - h = h*31 + _useMask; - return h; -} - -@end - -@implementation MTLGradPaint { - jdouble _p0; - jdouble _p1; - jdouble _p3; - jint _pixel1; - jint _pixel2; -} -- (id)initWithUseMask:(jboolean)useMask - cyclic:(jboolean)cyclic - p0:(jdouble)p0 - p1:(jdouble)p1 - p3:(jdouble)p3 - pixel1:(jint)pixel1 - pixel2:(jint)pixel2 -{ - self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_GRADIENT - mask:useMask - cyclic:cyclic]; - - if (self) { - _p0 = p0; - _p1 = p1; - _p3 = p3; - _pixel1 = pixel1; - _pixel2 = pixel2; - } - return self; -} - -- (BOOL)isEqual:(MTLGradPaint *)other { - if (other == self) - return YES; - if (!other || ![[other class] isEqual:[self class]]) - return NO; - - return [super isEqual:self] && _p0 == other->_p0 && - _p1 == other->_p1 && _p3 == other->_p3 && - _pixel1 == other->_pixel1 && _pixel2 == other->_pixel2; -} - -- (NSUInteger)hash { - NSUInteger h = [super hash]; - h = h*31 + [@(_p0) hash]; - h = h*31 + [@(_p1) hash];; - h = h*31 + [@(_p3) hash];; - h = h*31 + _pixel1; - h = h*31 + _pixel2; - return h; -} -- (NSString *)description { - return [NSString stringWithFormat:@"gradient"]; -} - -- (void)setPipelineState:(id)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - MTLRenderPipelineDescriptor *rpDesc = nil; - - NSString *vertShader = @"vert_grad"; - NSString *fragShader = @"frag_grad"; - - struct GradFrameUniforms uf = { - {_p0, _p1, _p3}, - RGBA_TO_V4(_pixel1), - RGBA_TO_V4(_pixel2), - _cyclic, - [mtlc.composite getExtraAlpha] - }; - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:0]; - - if (renderOptions->isTexture) { - vertShader = @"vert_txt_grad"; - fragShader = @"frag_txt_grad"; - rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - } else { - rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - } - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} - -- (void)setXorModePipelineState:(id)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - // This block is not reached in current implementation. - // Gradient paint XOR mode rendering uses a tile based rendering using a SW pipe (similar to OGL) - initTemplatePipelineDescriptors(); - NSString* vertShader = @"vert_grad_xorMode"; - NSString* fragShader = @"frag_grad_xorMode"; - MTLRenderPipelineDescriptor *rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - jint xorColor = (jint) [mtlc.composite getXorColor]; - - struct GradFrameUniforms uf = { - {_p0, _p1, _p3}, - RGBA_TO_V4(_pixel1 ^ xorColor), - RGBA_TO_V4(_pixel2 ^ xorColor), - _cyclic, - [mtlc.composite getExtraAlpha] - }; - - [encoder setFragmentBytes: &uf length:sizeof(uf) atIndex:0]; - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - [encoder setFragmentTexture:dstOps->pTexture atIndex:0]; - - J2dTraceLn(J2D_TRACE_INFO, "MTLPaints - setXorModePipelineState -- PAINT_GRADIENT"); - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} - -@end - -@implementation MTLBaseMultiGradPaint { - @protected - jboolean _linear; - jint _numFracts; - jfloat _fract[GRAD_MAX_FRACTIONS]; - jint _pixel[GRAD_MAX_FRACTIONS]; -} - -- (id)initWithState:(jint)state - mask:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jboolean)cycleMethod - numStops:(jint)numStops - fractions:(jfloat *)fractions - pixels:(jint *)pixels -{ - self = [super initWithState:state - mask:useMask - cyclic:cycleMethod]; - - if (self) { - _linear = linear; - memcpy(_fract, fractions,numStops*sizeof(jfloat)); - memcpy(_pixel, pixels, numStops*sizeof(jint)); - _numFracts = numStops; - } - return self; -} - -- (BOOL)isEqual:(MTLBaseMultiGradPaint *)other { - if (other == self) - return YES; - if (!other || ![[other class] isEqual:[self class]]) - return NO; - - if (_numFracts != other->_numFracts || ![super isEqual:self]) - return NO; - for (int i = 0; i < _numFracts; i++) { - if (_fract[i] != other->_fract[i]) return NO; - if (_pixel[i] != other->_pixel[i]) return NO; - } - return YES; -} - -- (NSUInteger)hash { - NSUInteger h = [super hash]; - h = h*31 + _numFracts; - for (int i = 0; i < _numFracts; i++) { - h = h*31 + [@(_fract[i]) hash]; - h = h*31 + _pixel[i]; - } - return h; -} - -@end - -@implementation MTLLinearGradPaint { - jdouble _p0; - jdouble _p1; - jdouble _p3; -} -- (void)setPipelineState:(id)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage - -{ - initTemplatePipelineDescriptors(); - MTLRenderPipelineDescriptor *rpDesc = nil; - - NSString *vertShader = @"vert_grad"; - NSString *fragShader = @"frag_lin_grad"; - - if (renderOptions->isTexture) { - vertShader = @"vert_txt_grad"; - fragShader = @"frag_txt_lin_grad"; - rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - } else { - rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - } - - struct LinGradFrameUniforms uf = { - {_p0, _p1, _p3}, - {}, - {}, - _numFracts, - _linear, - _cyclic, - [mtlc.composite getExtraAlpha] - }; - - memcpy(uf.fract, _fract, _numFracts*sizeof(jfloat)); - for (int i = 0; i < _numFracts; i++) { - vector_float4 v = RGBA_TO_V4(_pixel[i]); - uf.color[i] = v; - } - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:0]; - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} - -- (id)initWithUseMask:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jboolean)cycleMethod - numStops:(jint)numStops - p0:(jfloat)p0 - p1:(jfloat)p1 - p3:(jfloat)p3 - fractions:(jfloat *)fractions - pixels:(jint *)pixels -{ - self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_LIN_GRADIENT - mask:useMask - linear:linear - cycleMethod:cycleMethod - numStops:numStops - fractions:fractions - pixels:pixels]; - - if (self) { - _p0 = p0; - _p1 = p1; - _p3 = p3; - } - return self; -} - -- (BOOL)isEqual:(MTLLinearGradPaint *)other { - if (other == self) - return YES; - if (!other || ![[other class] isEqual:[self class]] || ![super isEqual:other]) - return NO; - - return _p0 == other->_p0 && _p1 == other->_p1 && _p3 == other->_p3; -} - -- (NSUInteger)hash { - NSUInteger h = [super hash]; - h = h*31 + [@(_p0) hash]; - h = h*31 + [@(_p1) hash]; - h = h*31 + [@(_p3) hash]; - return h; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"linear_gradient"]; -} -@end - -@implementation MTLRadialGradPaint { - jfloat _m00; - jfloat _m01; - jfloat _m02; - jfloat _m10; - jfloat _m11; - jfloat _m12; - jfloat _focusX; -} - -- (id)initWithUseMask:(jboolean)useMask - linear:(jboolean)linear - cycleMethod:(jint)cycleMethod - numStops:(jint)numStops - m00:(jfloat)m00 - m01:(jfloat)m01 - m02:(jfloat)m02 - m10:(jfloat)m10 - m11:(jfloat)m11 - m12:(jfloat)m12 - focusX:(jfloat)focusX - fractions:(void *)fractions - pixels:(void *)pixels -{ - self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_RAD_GRADIENT - mask:useMask - linear:linear - cycleMethod:cycleMethod - numStops:numStops - fractions:fractions - pixels:pixels]; - - if (self) { - _m00 = m00; - _m01 = m01; - _m02 = m02; - _m10 = m10; - _m11 = m11; - _m12 = m12; - _focusX = focusX; - } - return self; -} - -- (BOOL)isEqual:(MTLRadialGradPaint *)other { - if (other == self) - return YES; - if (!other || ![[other class] isEqual:[self class]] - || ![super isEqual:self]) - return NO; - - return _m00 == other->_m00 && _m01 == other->_m01 && _m02 == other->_m02 && - _m10 == other->_m10 && _m11 == other->_m11 && _m12 == other->_m12 && - _focusX == other->_focusX; -} - -- (NSUInteger)hash { - NSUInteger h = [super hash]; - h = h*31 + [@(_m00) hash]; - h = h*31 + [@(_m01) hash]; - h = h*31 + [@(_m02) hash]; - h = h*31 + [@(_m10) hash]; - h = h*31 + [@(_m11) hash]; - h = h*31 + [@(_m12) hash]; - return h; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"radial_gradient"]; -} - -- (void)setPipelineState:(id)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - MTLRenderPipelineDescriptor *rpDesc = nil; - - NSString *vertShader = @"vert_grad"; - NSString *fragShader = @"frag_rad_grad"; - - if (renderOptions->isTexture) { - vertShader = @"vert_txt_grad"; - fragShader = @"frag_txt_rad_grad"; - rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - } else { - rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - } - - struct RadGradFrameUniforms uf = { - {}, - {}, - _numFracts, - _linear, - _cyclic, - {_m00, _m01, _m02}, - {_m10, _m11, _m12}, - {}, - [mtlc.composite getExtraAlpha] - }; - - uf.precalc[0] = _focusX; - uf.precalc[1] = 1.0 - (_focusX * _focusX); - uf.precalc[2] = 1.0 / uf.precalc[1]; - - memcpy(uf.fract, _fract, _numFracts*sizeof(jfloat)); - for (int i = 0; i < _numFracts; i++) { - vector_float4 v = RGBA_TO_V4(_pixel[i]); - uf.color[i] = v; - } - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:0]; - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} - - -@end - -@implementation MTLTexturePaint { - struct AnchorData _anchor; - id <MTLTexture> _paintTexture; - jboolean _isOpaque; -} - -- (id)initWithUseMask:(jboolean)useMask - textureID:(id)textureId - isOpaque:(jboolean)isOpaque - filter:(jboolean)filter - xp0:(jdouble)xp0 - xp1:(jdouble)xp1 - xp3:(jdouble)xp3 - yp0:(jdouble)yp0 - yp1:(jdouble)yp1 - yp3:(jdouble)yp3 -{ - self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_TEXTURE]; - - if (self) { - _paintTexture = textureId; - _anchor.xParams[0] = xp0; - _anchor.xParams[1] = xp1; - _anchor.xParams[2] = xp3; - - _anchor.yParams[0] = yp0; - _anchor.yParams[1] = yp1; - _anchor.yParams[2] = yp3; - _isOpaque = isOpaque; - } - return self; - -} - -- (BOOL)isEqual:(MTLTexturePaint *)other { - if (other == self) - return YES; - if (!other || ![[other class] isEqual:[self class]]) - return NO; - - return [_paintTexture isEqual:other->_paintTexture] - && _anchor.xParams[0] == other->_anchor.xParams[0] - && _anchor.xParams[1] == other->_anchor.xParams[1] - && _anchor.xParams[2] == other->_anchor.xParams[2] - && _anchor.yParams[0] == other->_anchor.yParams[0] - && _anchor.yParams[1] == other->_anchor.yParams[1] - && _anchor.yParams[2] == other->_anchor.yParams[2]; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"texture_paint"]; -} - -- (void)setPipelineState:(id)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - MTLRenderPipelineDescriptor *rpDesc = nil; - - NSString* vertShader = @"vert_tp"; - NSString* fragShader = @"frag_tp"; - - [encoder setVertexBytes:&_anchor length:sizeof(_anchor) atIndex:FrameUniformBuffer]; - - if (renderOptions->isTexture) { - vertShader = @"vert_txt_tp"; - fragShader = @"frag_txt_tp"; - rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - [encoder setFragmentTexture:_paintTexture atIndex:1]; - } else { - rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - [encoder setFragmentTexture:_paintTexture atIndex:0]; - } - const SurfaceRasterFlags srcFlags = {_isOpaque, renderOptions->srcFlags.isPremultiplied}; - setTxtUniforms(mtlc, 0, encoder, - renderOptions->interpolation, YES, [mtlc.composite getExtraAlpha], - &srcFlags, &renderOptions->dstFlags, 0); - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} - -- (void)setXorModePipelineState:(id)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - // This block is not reached in current implementation. - // Texture paint XOR mode rendering uses a tile based rendering using a SW pipe (similar to OGL) - NSString* vertShader = @"vert_tp_xorMode"; - NSString* fragShader = @"frag_tp_xorMode"; - MTLRenderPipelineDescriptor *rpDesc = [[templateRenderPipelineDesc copy] autorelease]; - jint xorColor = (jint) [mtlc.composite getXorColor]; - - [encoder setVertexBytes:&_anchor length:sizeof(_anchor) atIndex:FrameUniformBuffer]; - [encoder setFragmentTexture:_paintTexture atIndex: 0]; - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - [encoder setFragmentTexture:dstOps->pTexture atIndex:1]; - [encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex: 0]; - - J2dTraceLn(J2D_TRACE_INFO, "MTLPaints - setXorModePipelineState -- PAINT_TEXTURE"); - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; -} - -@end - -@implementation MTLPaint { - jint _paintState; -} - -- (instancetype)init { - self = [super init]; - if (self) { - _paintState = sun_java2d_SunGraphics2D_PAINT_UNDEFINED; - } - - return self; -} - -- (instancetype)initWithState:(jint)state { - self = [super init]; - if (self) { - _paintState = state; - } - return self; -} - -- (BOOL)isEqual:(MTLPaint *)other { - if (other == self) - return YES; - if (!other || ![other isKindOfClass:[self class]]) - return NO; - return _paintState == other->_paintState; -} - -- (NSUInteger)hash { - return _paintState; -} - -- (NSString *)description { - return @"unknown-paint"; -} - -static void -setTxtUniforms(MTLContext *mtlc, int color, id <MTLRenderCommandEncoder> encoder, int interpolation, bool repeat, - jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, const SurfaceRasterFlags *dstFlags, int mode) { - struct TxtFrameUniforms uf = {RGBA_TO_V4(color), mode, srcFlags->isOpaque, dstFlags->isOpaque, extraAlpha}; - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - [mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:interpolation repeat:repeat]; -} - -// For the current paint mode: -// 1. Selects vertex+fragment shaders (and corresponding pipelineDesc) and set pipelineState -// 2. Set vertex and fragment buffers -// Base implementation is used in drawTex2Tex -- (void)setPipelineState:(id <MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - // Called from drawTex2Tex used in flushBuffer and for buffered image ops - if (renderOptions->isTexture) { - NSString * vertShader = @"vert_txt"; - NSString * fragShader = @"frag_txt"; - MTLRenderPipelineDescriptor* rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - - NSObject *bufImgOp = [mtlc getBufImgOp]; - if (bufImgOp != nil) { - if ([bufImgOp isKindOfClass:[MTLRescaleOp class]]) { - MTLRescaleOp *rescaleOp = bufImgOp; - fragShader = @"frag_txt_op_rescale"; - - struct TxtFrameOpRescaleUniforms uf = { - RGBA_TO_V4(0), [mtlc.composite getExtraAlpha], renderOptions->srcFlags.isOpaque, - rescaleOp.isNonPremult, - FLOAT_ARR_TO_V4([rescaleOp getScaleFactors]), FLOAT_ARR_TO_V4([rescaleOp getOffsets]) - }; - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - [mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:renderOptions->interpolation repeat:NO]; - } else if ([bufImgOp isKindOfClass:[MTLConvolveOp class]]) { - MTLConvolveOp *convolveOp = bufImgOp; - fragShader = @"frag_txt_op_convolve"; - - struct TxtFrameOpConvolveUniforms uf = { - [mtlc.composite getExtraAlpha], renderOptions->srcFlags.isOpaque, - FLOAT_ARR_TO_V4([convolveOp getImgEdge]), - convolveOp.kernelSize, convolveOp.isEdgeZeroFill, - }; - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - [mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:renderOptions->interpolation repeat:NO]; - - [encoder setFragmentBuffer:[convolveOp getBuffer] offset:0 atIndex:2]; - } else if ([bufImgOp isKindOfClass:[MTLLookupOp class]]) { - MTLLookupOp *lookupOp = bufImgOp; - fragShader = @"frag_txt_op_lookup"; - - struct TxtFrameOpLookupUniforms uf = { - [mtlc.composite getExtraAlpha], renderOptions->srcFlags.isOpaque, - FLOAT_ARR_TO_V4([lookupOp getOffset]), lookupOp.isUseSrcAlpha, lookupOp.isNonPremult, - }; - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - [mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:renderOptions->interpolation repeat:NO]; - [encoder setFragmentTexture:[lookupOp getLookupTexture] atIndex:1]; - } - } else { - setTxtUniforms(mtlc, 0, encoder, - renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, - &renderOptions->dstFlags, 0); - - } - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; - } -} - -// For the current paint mode: -// 1. Selects vertex+fragment shaders (and corresponding pipelineDesc) and set pipelineState -// 2. Set vertex and fragment buffers -- (void)setXorModePipelineState:(id <MTLRenderCommandEncoder>)encoder - context:(MTLContext *)mtlc - renderOptions:(const RenderOptions *)renderOptions - pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage -{ - initTemplatePipelineDescriptors(); - if (renderOptions->isTexture) { - jint xorColor = (jint) [mtlc.composite getXorColor]; - NSString * vertShader = @"vert_txt_xorMode"; - NSString * fragShader = @"frag_txt_xorMode"; - MTLRenderPipelineDescriptor * rpDesc = [[templateTexturePipelineDesc copy] autorelease]; - - const int col = 0 ^ xorColor; - setTxtUniforms(mtlc, col, encoder, - renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, &renderOptions->dstFlags, 0); - [encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex: 0]; - - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - [encoder setFragmentTexture:dstOps->pTexture atIndex:1]; - - setTxtUniforms(mtlc, 0, encoder, - renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, - &renderOptions->dstFlags, 0); - - id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc - vertexShaderId:vertShader - fragmentShaderId:fragShader - composite:mtlc.composite - renderOptions:renderOptions - stencilNeeded:[mtlc.clip isShape]]; - [encoder setRenderPipelineState:pipelineState]; - } -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.h deleted file mode 100644 index 527250be971..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLPipelineStatesStorage_h_Included -#define MTLPipelineStatesStorage_h_Included - -#import "MTLUtils.h" -#include "RenderOptions.h" - -@class MTLComposite; - -/** - * The MTLPipelineStatesStorage class used to obtain MTLRenderPipelineState - * */ - - -@interface MTLPipelineStatesStorage : NSObject { -@private - -id<MTLDevice> device; -id<MTLLibrary> library; -NSMutableDictionary<NSString*, id<MTLFunction>> * shaders; -NSMutableDictionary<NSString*, id<MTLComputePipelineState>> * computeStates; -} - -@property (readwrite, assign) id<MTLDevice> device; -@property (readwrite, retain) id<MTLLibrary> library; -@property (readwrite, retain) NSMutableDictionary<NSString*, id<MTLFunction>> * shaders; -@property (readwrite, retain) NSMutableDictionary<NSString*, NSMutableDictionary *> * states; - -- (id) initWithDevice:(id<MTLDevice>)device shaderLibPath:(NSString *)shadersLib; - -- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor - vertexShaderId:(NSString *)vertexShaderId - fragmentShaderId:(NSString *)fragmentShaderId; - -- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor - vertexShaderId:(NSString *)vertexShaderId - fragmentShaderId:(NSString *)fragmentShaderId - stencilNeeded:(bool)stencilNeeded; - -- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor - vertexShaderId:(NSString *)vertexShaderId - fragmentShaderId:(NSString *)fragmentShaderId - composite:(MTLComposite*)composite - renderOptions:(const RenderOptions *)renderOptions - stencilNeeded:(bool)stencilNeeded; - -- (id<MTLComputePipelineState>) getComputePipelineState:(NSString *)computeShaderId; - -- (id<MTLFunction>) getShader:(NSString *)name; -@end - - -#endif // MTLPipelineStatesStorage_h_Included diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m deleted file mode 100644 index 0928f12d426..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#import "MTLPipelineStatesStorage.h" - -#include "GraphicsPrimitiveMgr.h" -#import "MTLComposite.h" - -#include "sun_java2d_SunGraphics2D.h" - -extern const SurfaceRasterFlags defaultRasterFlags; - -static void setBlendingFactors( - MTLRenderPipelineColorAttachmentDescriptor * cad, - MTLComposite* composite, - const RenderOptions * renderOptions); - -@implementation MTLPipelineStatesStorage - -@synthesize device; -@synthesize library; -@synthesize shaders; -@synthesize states; - -- (id) initWithDevice:(id<MTLDevice>)dev shaderLibPath:(NSString *)shadersLib { - self = [super init]; - if (self == nil) return self; - - self.device = dev; - - NSError *error = nil; - self.library = [dev newLibraryWithFile:shadersLib error:&error]; - if (!self.library) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLPipelineStatesStorage.initWithDevice() - Failed to load Metal shader library."); - return nil; - } - self.shaders = [NSMutableDictionary dictionaryWithCapacity:10]; - self.states = [NSMutableDictionary dictionaryWithCapacity:10]; - computeStates = [[NSMutableDictionary dictionaryWithCapacity:10] retain] ; - return self; -} - -- (NSPointerArray * ) getSubStates:(NSString *)vertexShaderId fragmentShader:(NSString *)fragmentShaderId { - NSMutableDictionary * vSubStates = states[vertexShaderId]; - if (vSubStates == nil) { - @autoreleasepool { - vSubStates = [NSMutableDictionary dictionary]; - [states setObject:vSubStates forKey:vertexShaderId]; - } - } - NSPointerArray * sSubStates = vSubStates[fragmentShaderId]; - if (sSubStates == nil) { - @autoreleasepool { - sSubStates = [NSPointerArray strongObjectsPointerArray]; - [vSubStates setObject:sSubStates forKey:fragmentShaderId]; - } - } - return sSubStates; -} - -- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor - vertexShaderId:(NSString *)vertexShaderId - fragmentShaderId:(NSString *)fragmentShaderId -{ - RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, {JNI_FALSE, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; - return [self getPipelineState:pipelineDescriptor - vertexShaderId:vertexShaderId - fragmentShaderId:fragmentShaderId - composite:nil - renderOptions:&defaultOptions - stencilNeeded:NO]; -} - -- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor - vertexShaderId:(NSString *)vertexShaderId - fragmentShaderId:(NSString *)fragmentShaderId - stencilNeeded:(bool)stencilNeeded -{ - RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, {JNI_FALSE, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; - return [self getPipelineState:pipelineDescriptor - vertexShaderId:vertexShaderId - fragmentShaderId:fragmentShaderId - composite:nil - renderOptions:&defaultOptions - stencilNeeded:stencilNeeded]; -} - -// Base method to obtain MTLRenderPipelineState. -// NOTE: parameters compositeRule, srcFlags, dstFlags are used to set MTLRenderPipelineColorAttachmentDescriptor multipliers -- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor - vertexShaderId:(NSString *)vertexShaderId - fragmentShaderId:(NSString *)fragmentShaderId - composite:(MTLComposite*) composite - renderOptions:(const RenderOptions *)renderOptions - stencilNeeded:(bool)stencilNeeded; -{ - jint compositeRule = composite != nil ? [composite getRule] : RULE_Src; - const jboolean useXorComposite = composite != nil && [composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR; - const jboolean useComposite = composite != nil && compositeRule >= 0 - && compositeRule < java_awt_AlphaComposite_MAX_RULE; - - // Calculate index by flags and compositeRule - // TODO: reimplement, use map with convenient key (calculated by all arguments) - int subIndex = 0; - if (useXorComposite) { - // compositeRule value is already XOR_COMPOSITE_RULE - } - else { - if (useComposite) { - if (!renderOptions->srcFlags.isPremultiplied) - subIndex |= 1; - if (renderOptions->srcFlags.isOpaque) - subIndex |= 1 << 1; - if (!renderOptions->dstFlags.isPremultiplied) - subIndex |= 1 << 2; - if (renderOptions->dstFlags.isOpaque) - subIndex |= 1 << 3; - } else - compositeRule = RULE_Src; - } - - if (stencilNeeded) { - subIndex |= 1 << 4; - } - - if (renderOptions->isAA) { - subIndex |= 1 << 5; - } - - if ((composite != nil && FLT_LT([composite getExtraAlpha], 1.0f))) { - subIndex |= 1 << 6; - } - - int index = compositeRule*128 + subIndex; - - NSPointerArray * subStates = [self getSubStates:vertexShaderId fragmentShader:fragmentShaderId]; - - if (index >= subStates.count) { - subStates.count = (NSUInteger) (index + 1); - } - - id<MTLRenderPipelineState> result = [subStates pointerAtIndex:index]; - if (result == nil) { - @autoreleasepool { - id <MTLFunction> vertexShader = [self getShader:vertexShaderId]; - id <MTLFunction> fragmentShader = [self getShader:fragmentShaderId]; - MTLRenderPipelineDescriptor *pipelineDesc = [[pipelineDescriptor copy] autorelease]; - pipelineDesc.vertexFunction = vertexShader; - pipelineDesc.fragmentFunction = fragmentShader; - - if (useXorComposite) { - /* The below configuration is the best performant implementation of XOR mode rendering. - It was found that it works ONLY for basic Colors and not for all RGB combinations. - Hence, a slow performant XOR mode rendering has been implemented by - disabling blending & committing after each draw call. - In XOR mode rendering, subsequent draw calls are rendered - by shader using already rendered framebuffer pixel value XORed - with current draw color and XOR color. - pipelineDesc.colorAttachments[0].blendingEnabled = YES; - pipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - pipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOneMinusDestinationColor; - pipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceColor; - */ - - pipelineDesc.colorAttachments[0].blendingEnabled = NO; - } else if (useComposite || - (composite != nil && - FLT_LT([composite getExtraAlpha], 1.0f))) - { - setBlendingFactors( - pipelineDesc.colorAttachments[0], - composite, - renderOptions - ); - } - if (stencilNeeded) { - pipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatStencil8; - } else { - // We continue to use same encoder when we move from shape clip - // to other opcodes. So we need to maintain apprppriate state - // for stencilAttachmentPixelFormat until we end the encoder - pipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatInvalid; - } - - if (renderOptions->isAA) { - pipelineDesc.sampleCount = MTLAASampleCount; - pipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - pipelineDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; - pipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne; - pipelineDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; - pipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - pipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - pipelineDesc.colorAttachments[0].blendingEnabled = YES; - } - - NSError *error = nil; - result = [[self.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error] autorelease]; - if (result == nil) { - NSLog(@"Failed to create pipeline state, error %@", error); - exit(0); - } - - [subStates insertPointer:result atIndex:index]; - } - } - - return result; -} - -- (id<MTLComputePipelineState>) getComputePipelineState:(NSString *)computeShaderId { - id<MTLComputePipelineState> result = computeStates[computeShaderId]; - if (result == nil) { - id <MTLFunction> computeShader = [self getShader:computeShaderId]; - @autoreleasepool { - NSError *error = nil; - result = (id <MTLComputePipelineState>) [[self.device newComputePipelineStateWithFunction:computeShader error:&error] autorelease]; - if (result == nil) { - NSLog(@"Failed to create pipeline state, error %@", error); - exit(0); - } - computeStates[computeShaderId] = result; - } - } - return result; -} - -- (id<MTLFunction>) getShader:(NSString *)name { - id<MTLFunction> result = [self.shaders valueForKey:name]; - if (result == nil) { - result = [[self.library newFunctionWithName:name] autorelease]; - [self.shaders setValue:result forKey:name]; - } - return result; -} - -- (void) dealloc { - [super dealloc]; - [computeStates release]; -} -@end - -/** - * The MTLBlendRule structure encapsulates the two enumerated values that - * comprise a given Porter-Duff blending (compositing) rule. For example, - * the "SrcOver" rule can be represented by: - * rule.src = MTLBlendFactorZero; - * rule.dst = MTLBlendFactorOneMinusSourceAlpha; - * - * MTLBlendFactor src; - * The constant representing the source factor in this Porter-Duff rule. - * - * MTLBlendFactor dst; - * The constant representing the destination factor in this Porter-Duff rule. - */ -struct MTLBlendRule { - MTLBlendFactor src; - MTLBlendFactor dst; -}; - -/** - * This table contains the standard blending rules (or Porter-Duff compositing - * factors) used in setBlendingFactors(), indexed by the rule constants from the - * AlphaComposite class. - */ -static struct MTLBlendRule StdBlendRules[] = { - { MTLBlendFactorZero, MTLBlendFactorZero }, /* 0 - Nothing */ - { MTLBlendFactorZero, MTLBlendFactorZero }, /* 1 - RULE_Clear */ - { MTLBlendFactorOne, MTLBlendFactorZero }, /* 2 - RULE_Src */ - { MTLBlendFactorOne, MTLBlendFactorOneMinusSourceAlpha }, /* 3 - RULE_SrcOver */ - { MTLBlendFactorOneMinusDestinationAlpha, MTLBlendFactorOne }, /* 4 - RULE_DstOver */ - { MTLBlendFactorDestinationAlpha, MTLBlendFactorZero }, /* 5 - RULE_SrcIn */ - { MTLBlendFactorZero, MTLBlendFactorSourceAlpha }, /* 6 - RULE_DstIn */ - { MTLBlendFactorOneMinusDestinationAlpha, MTLBlendFactorZero }, /* 7 - RULE_SrcOut */ - { MTLBlendFactorZero, MTLBlendFactorOneMinusSourceAlpha }, /* 8 - RULE_DstOut */ - { MTLBlendFactorZero, MTLBlendFactorOne }, /* 9 - RULE_Dst */ - { MTLBlendFactorDestinationAlpha, MTLBlendFactorOneMinusSourceAlpha }, /*10 - RULE_SrcAtop */ - { MTLBlendFactorOneMinusDestinationAlpha, MTLBlendFactorSourceAlpha }, /*11 - RULE_DstAtop */ - { MTLBlendFactorOneMinusDestinationAlpha, MTLBlendFactorOneMinusSourceAlpha }, /*12 - RULE_AlphaXor*/ -}; - -static void setBlendingFactors( - MTLRenderPipelineColorAttachmentDescriptor * cad, - MTLComposite* composite, - const RenderOptions * renderOptions -) { - const long compositeRule = composite != nil ? [composite getRule] : RULE_Src; - - if ((compositeRule == RULE_Src || compositeRule == RULE_SrcOver) && - (composite == nil || FLT_GE([composite getExtraAlpha], 1.0f)) && - (renderOptions->srcFlags.isOpaque)) - { - cad.blendingEnabled = NO; - return; - } - - cad.blendingEnabled = YES; - cad.rgbBlendOperation = MTLBlendOperationAdd; - cad.alphaBlendOperation = MTLBlendOperationAdd; - - cad.sourceAlphaBlendFactor = StdBlendRules[compositeRule].src; - cad.sourceRGBBlendFactor = StdBlendRules[compositeRule].src; - cad.destinationAlphaBlendFactor = StdBlendRules[compositeRule].dst; - cad.destinationRGBBlendFactor = StdBlendRules[compositeRule].dst; -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.h deleted file mode 100644 index 7231bfd026e..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLRenderQueue_h_Included -#define MTLRenderQueue_h_Included - -#include "MTLContext.h" -#include "MTLSurfaceData.h" -#include "MTLVertexCache.h" - -/* - * The following macros are used to pick values (of the specified type) off - * the queue. - */ -#define NEXT_VAL(buf, type) (((type *)((buf) += sizeof(type)))[-1]) -#define NEXT_BYTE(buf) NEXT_VAL(buf, unsigned char) -#define NEXT_INT(buf) NEXT_VAL(buf, jint) -#define NEXT_FLOAT(buf) NEXT_VAL(buf, jfloat) -#define NEXT_BOOLEAN(buf) (jboolean)NEXT_INT(buf) -#define NEXT_LONG(buf) NEXT_VAL(buf, jlong) -#define NEXT_DOUBLE(buf) NEXT_VAL(buf, jdouble) - -// Operations for CheckPreviousOp -enum { - MTL_OP_INIT, - MTL_OP_AA, - MTL_OP_SET_COLOR, - MTL_OP_RESET_PAINT, - MTL_OP_SYNC, - MTL_OP_SHAPE_CLIP_SPANS, - MTL_OP_MASK_OP, - MTL_OP_OTHER -}; -/* - * These macros now simply delegate to the CheckPreviousOp() method. - */ -#define CHECK_PREVIOUS_OP(op) MTLRenderQueue_CheckPreviousOp(op) -#define RESET_PREVIOUS_OP() {mtlPreviousOp = MTL_OP_INIT;} - -/* - * Increments a pointer (buf) by the given number of bytes. - */ -#define SKIP_BYTES(buf, numbytes) buf += (numbytes) - -/* - * Extracts a value at the given offset from the provided packed value. - */ -#define EXTRACT_VAL(packedval, offset, mask) \ - (((packedval) >> (offset)) & (mask)) -#define EXTRACT_BYTE(packedval, offset) \ - (unsigned char)EXTRACT_VAL(packedval, offset, 0xff) -#define EXTRACT_BOOLEAN(packedval, offset) \ - (jboolean)EXTRACT_VAL(packedval, offset, 0x1) - -/* - * The following macros allow the caller to return (or continue) if the - * provided value is NULL. (The strange else clause is included below to - * allow for a trailing ';' after RETURN/CONTINUE_IF_NULL() invocations.) - */ -#define ACT_IF_NULL(ACTION, value) \ - if ((value) == NULL) { \ - J2dTraceLn1(J2D_TRACE_ERROR, \ - "%s is null", #value); \ - ACTION; \ - } else do { } while (0) -#define RETURN_IF_NULL(value) ACT_IF_NULL(return, value) -#define CONTINUE_IF_NULL(value) ACT_IF_NULL(continue, value) - -#define ACT_IF_TRUE(ACTION, value) \ - if ((value)) { \ - J2dTraceLn1(J2D_TRACE_ERROR, \ - "%s is false", #value);\ - ACTION; \ - } else do { } while (0) - -#define RETURN_IF_TRUE(value) ACT_IF_TRUE(return, value) - -MTLContext *MTLRenderQueue_GetCurrentContext(); -BMTLSDOps *MTLRenderQueue_GetCurrentDestination(); -void commitEncodedCommands(); - -extern jint mtlPreviousOp; - -#endif /* MTLRenderQueue_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m deleted file mode 100644 index b479ba6fbfd..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <stdlib.h> - -#include "sun_java2d_pipe_BufferedOpCodes.h" - -#include "jlong.h" -#include "MTLBlitLoops.h" -#include "MTLBufImgOps.h" -#include "MTLMaskBlit.h" -#include "MTLMaskFill.h" -#include "MTLPaints.h" -#include "MTLRenderQueue.h" -#include "MTLRenderer.h" -#include "MTLTextRenderer.h" -#import "ThreadUtilities.h" - -/** - * References to the "current" context and destination surface. - */ -static MTLContext *mtlc = NULL; -static BMTLSDOps *dstOps = NULL; -jint mtlPreviousOp = MTL_OP_INIT; - - -extern void MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo); - -void MTLRenderQueue_CheckPreviousOp(jint op) { - - if (mtlPreviousOp == op) { - // The op is the same as last time, so we can return immediately. - return; - } - - if (op == MTL_OP_SET_COLOR) { - if (mtlPreviousOp != MTL_OP_MASK_OP) { - return; // SET_COLOR should not cause endEncoder - } - } else if (op == MTL_OP_MASK_OP) { - MTLVertexCache_EnableMaskCache(mtlc, dstOps); - mtlPreviousOp = op; - return; - } - - J2dTraceLn1(J2D_TRACE_VERBOSE, - "MTLRenderQueue_CheckPreviousOp: new op=%d", op); - - switch (mtlPreviousOp) { - case MTL_OP_INIT : - mtlPreviousOp = op; - return; - case MTL_OP_MASK_OP : - MTLVertexCache_DisableMaskCache(mtlc); - break; - } - - if (mtlc != NULL) { - [mtlc.encoderManager endEncoder]; - - if (op == MTL_OP_RESET_PAINT || op == MTL_OP_SYNC || op == MTL_OP_SHAPE_CLIP_SPANS) { - MTLCommandBufferWrapper *cbwrapper = [mtlc pullCommandBufferWrapper]; - id <MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - if (op == MTL_OP_SYNC || op == MTL_OP_SHAPE_CLIP_SPANS) { - [commandbuf waitUntilCompleted]; - } - } - } - mtlPreviousOp = op; -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLRenderQueue_flushBuffer - (JNIEnv *env, jobject mtlrq, - jlong buf, jint limit) -{ - unsigned char *b, *end; - - J2dTraceLn1(J2D_TRACE_INFO, - "MTLRenderQueue_flushBuffer: limit=%d", limit); - - b = (unsigned char *)jlong_to_ptr(buf); - if (b == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLRenderQueue_flushBuffer: cannot get direct buffer address"); - return; - } - - end = b + limit; - @autoreleasepool { - while (b < end) { - jint opcode = NEXT_INT(b); - - J2dTraceLn2(J2D_TRACE_VERBOSE, - "MTLRenderQueue_flushBuffer: opcode=%d, rem=%d", - opcode, (end-b)); - - switch (opcode) { - - // draw ops - case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "DRAW_LINE in XOR mode - Force commit earlier draw calls before DRAW_LINE."); - } - jint x1 = NEXT_INT(b); - jint y1 = NEXT_INT(b); - jint x2 = NEXT_INT(b); - jint y2 = NEXT_INT(b); - MTLRenderer_DrawLine(mtlc, dstOps, x1, y1, x2, y2); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "DRAW_RECT in XOR mode - Force commit earlier draw calls before DRAW_RECT."); - } - jint x = NEXT_INT(b); - jint y = NEXT_INT(b); - jint w = NEXT_INT(b); - jint h = NEXT_INT(b); - MTLRenderer_DrawRect(mtlc, dstOps, x, y, w, h); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint nPoints = NEXT_INT(b); - jboolean isClosed = NEXT_BOOLEAN(b); - jint transX = NEXT_INT(b); - jint transY = NEXT_INT(b); - jint *xPoints = (jint *)b; - jint *yPoints = ((jint *)b) + nPoints; - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "DRAW_POLY in XOR mode - Force commit earlier draw calls before DRAW_POLY."); - - // draw separate (N-1) lines using N points - for(int point = 0; point < nPoints-1; point++) { - jint x1 = xPoints[point] + transX; - jint y1 = yPoints[point] + transY; - jint x2 = xPoints[point + 1] + transX; - jint y2 = yPoints[point + 1] + transY; - MTLRenderer_DrawLine(mtlc, dstOps, x1, y1, x2, y2); - } - - if (isClosed) { - MTLRenderer_DrawLine(mtlc, dstOps, xPoints[0] + transX, yPoints[0] + transY, - xPoints[nPoints-1] + transX, yPoints[nPoints-1] + transY); - } - } else { - MTLRenderer_DrawPoly(mtlc, dstOps, nPoints, isClosed, transX, transY, xPoints, yPoints); - } - - SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "DRAW_PIXEL in XOR mode - Force commit earlier draw calls before DRAW_PIXEL."); - } - - jint x = NEXT_INT(b); - jint y = NEXT_INT(b); - CONTINUE_IF_NULL(mtlc); - MTLRenderer_DrawPixel(mtlc, dstOps, x, y); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "DRAW_SCANLINES in XOR mode - Force commit earlier draw calls before " - "DRAW_SCANLINES."); - } - - jint count = NEXT_INT(b); - MTLRenderer_DrawScanlines(mtlc, dstOps, count, (jint *)b); - - SKIP_BYTES(b, count * BYTES_PER_SCANLINE); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "DRAW_PARALLELOGRAM in XOR mode - Force commit earlier draw calls before " - "DRAW_PARALLELOGRAM."); - } - - jfloat x11 = NEXT_FLOAT(b); - jfloat y11 = NEXT_FLOAT(b); - jfloat dx21 = NEXT_FLOAT(b); - jfloat dy21 = NEXT_FLOAT(b); - jfloat dx12 = NEXT_FLOAT(b); - jfloat dy12 = NEXT_FLOAT(b); - jfloat lwr21 = NEXT_FLOAT(b); - jfloat lwr12 = NEXT_FLOAT(b); - - MTLRenderer_DrawParallelogram(mtlc, dstOps, - x11, y11, - dx21, dy21, - dx12, dy12, - lwr21, lwr12); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jfloat x11 = NEXT_FLOAT(b); - jfloat y11 = NEXT_FLOAT(b); - jfloat dx21 = NEXT_FLOAT(b); - jfloat dy21 = NEXT_FLOAT(b); - jfloat dx12 = NEXT_FLOAT(b); - jfloat dy12 = NEXT_FLOAT(b); - jfloat lwr21 = NEXT_FLOAT(b); - jfloat lwr12 = NEXT_FLOAT(b); - - MTLRenderer_DrawAAParallelogram(mtlc, dstOps, - x11, y11, - dx21, dy21, - dx12, dy12, - lwr21, lwr12); - break; - } - - // fill ops - case sun_java2d_pipe_BufferedOpCodes_FILL_RECT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "FILL_RECT in XOR mode - Force commit earlier draw calls before FILL_RECT."); - } - - jint x = NEXT_INT(b); - jint y = NEXT_INT(b); - jint w = NEXT_INT(b); - jint h = NEXT_INT(b); - MTLRenderer_FillRect(mtlc, dstOps, x, y, w, h); - break; - } - case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "FILL_SPANS in XOR mode - Force commit earlier draw calls before FILL_SPANS."); - } - - jint count = NEXT_INT(b); - MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b); - SKIP_BYTES(b, count * BYTES_PER_SPAN); - break; - } - case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "FILL_PARALLELOGRAM in XOR mode - Force commit earlier draw calls before " - "FILL_PARALLELOGRAM."); - } - - jfloat x11 = NEXT_FLOAT(b); - jfloat y11 = NEXT_FLOAT(b); - jfloat dx21 = NEXT_FLOAT(b); - jfloat dy21 = NEXT_FLOAT(b); - jfloat dx12 = NEXT_FLOAT(b); - jfloat dy12 = NEXT_FLOAT(b); - MTLRenderer_FillParallelogram(mtlc, dstOps, - x11, y11, - dx21, dy21, - dx12, dy12); - break; - } - case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jfloat x11 = NEXT_FLOAT(b); - jfloat y11 = NEXT_FLOAT(b); - jfloat dx21 = NEXT_FLOAT(b); - jfloat dy21 = NEXT_FLOAT(b); - jfloat dx12 = NEXT_FLOAT(b); - jfloat dy12 = NEXT_FLOAT(b); - MTLRenderer_FillAAParallelogram(mtlc, dstOps, - x11, y11, - dx21, dy21, - dx12, dy12); - break; - } - - // text-related ops - case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - - if ([mtlc useXORComposite]) { - commitEncodedCommands(); - J2dTraceLn(J2D_TRACE_VERBOSE, - "DRAW_GLYPH_LIST in XOR mode - Force commit earlier draw calls before " - "DRAW_GLYPH_LIST."); - } - - jint numGlyphs = NEXT_INT(b); - jint packedParams = NEXT_INT(b); - jfloat glyphListOrigX = NEXT_FLOAT(b); - jfloat glyphListOrigY = NEXT_FLOAT(b); - jboolean usePositions = EXTRACT_BOOLEAN(packedParams, - OFFSET_POSITIONS); - jboolean subPixPos = EXTRACT_BOOLEAN(packedParams, - OFFSET_SUBPIXPOS); - jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams, - OFFSET_RGBORDER); - jint lcdContrast = EXTRACT_BYTE(packedParams, - OFFSET_CONTRAST); - unsigned char *images = b; - unsigned char *positions; - jint bytesPerGlyph; - if (usePositions) { - positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE); - bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH; - } else { - positions = NULL; - bytesPerGlyph = BYTES_PER_GLYPH_IMAGE; - } - MTLTR_DrawGlyphList(env, mtlc, dstOps, - numGlyphs, usePositions, - subPixPos, rgbOrder, lcdContrast, - glyphListOrigX, glyphListOrigY, - images, positions); - SKIP_BYTES(b, numGlyphs * bytesPerGlyph); - break; - } - - // copy-related ops - case sun_java2d_pipe_BufferedOpCodes_COPY_AREA: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint x = NEXT_INT(b); - jint y = NEXT_INT(b); - jint w = NEXT_INT(b); - jint h = NEXT_INT(b); - jint dx = NEXT_INT(b); - jint dy = NEXT_INT(b); - MTLBlitLoops_CopyArea(env, mtlc, dstOps, - x, y, w, h, dx, dy); - break; - } - case sun_java2d_pipe_BufferedOpCodes_BLIT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint packedParams = NEXT_INT(b); - jint sx1 = NEXT_INT(b); - jint sy1 = NEXT_INT(b); - jint sx2 = NEXT_INT(b); - jint sy2 = NEXT_INT(b); - jdouble dx1 = NEXT_DOUBLE(b); - jdouble dy1 = NEXT_DOUBLE(b); - jdouble dx2 = NEXT_DOUBLE(b); - jdouble dy2 = NEXT_DOUBLE(b); - jlong pSrc = NEXT_LONG(b); - jlong pDst = NEXT_LONG(b); - jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT); - jboolean texture = EXTRACT_BOOLEAN(packedParams, - OFFSET_TEXTURE); - jboolean xform = EXTRACT_BOOLEAN(packedParams, - OFFSET_XFORM); - jboolean isoblit = EXTRACT_BOOLEAN(packedParams, - OFFSET_ISOBLIT); - if (isoblit) { - MTLBlitLoops_IsoBlit(env, mtlc, pSrc, pDst, - xform, hint, texture, - sx1, sy1, sx2, sy2, - dx1, dy1, dx2, dy2); - } else { - jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE); - MTLBlitLoops_Blit(env, mtlc, pSrc, pDst, - xform, hint, srctype, texture, - sx1, sy1, sx2, sy2, - dx1, dy1, dx2, dy2); - } - break; - } - case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint sx = NEXT_INT(b); - jint sy = NEXT_INT(b); - jint dx = NEXT_INT(b); - jint dy = NEXT_INT(b); - jint w = NEXT_INT(b); - jint h = NEXT_INT(b); - jint dsttype = NEXT_INT(b); - jlong pSrc = NEXT_LONG(b); - jlong pDst = NEXT_LONG(b); - MTLBlitLoops_SurfaceToSwBlit(env, mtlc, - pSrc, pDst, dsttype, - sx, sy, dx, dy, w, h); - break; - } - case sun_java2d_pipe_BufferedOpCodes_MASK_FILL: - { - jint x = NEXT_INT(b); - jint y = NEXT_INT(b); - jint w = NEXT_INT(b); - jint h = NEXT_INT(b); - jint maskoff = NEXT_INT(b); - jint maskscan = NEXT_INT(b); - jint masklen = NEXT_INT(b); - unsigned char *pMask = (masklen > 0) ? b : NULL; - if (mtlc == nil) - return; - CHECK_PREVIOUS_OP(MTL_OP_MASK_OP); - MTLMaskFill_MaskFill(mtlc, dstOps, x, y, w, h, - maskoff, maskscan, masklen, pMask); - SKIP_BYTES(b, masklen); - break; - } - case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint dstx = NEXT_INT(b); - jint dsty = NEXT_INT(b); - jint width = NEXT_INT(b); - jint height = NEXT_INT(b); - jint masklen = width * height * sizeof(jint); - MTLMaskBlit_MaskBlit(env, mtlc, dstOps, - dstx, dsty, width, height, b); - SKIP_BYTES(b, masklen); - break; - } - - // state-related ops - case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint x1 = NEXT_INT(b); - jint y1 = NEXT_INT(b); - jint x2 = NEXT_INT(b); - jint y2 = NEXT_INT(b); - [mtlc setClipRectX1:x1 Y1:y1 X2:x2 Y2:y2]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc beginShapeClip:dstOps]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS: - { - CHECK_PREVIOUS_OP(MTL_OP_SHAPE_CLIP_SPANS); - // This results in creation of new render encoder with - // stencil buffer set as render target - jint count = NEXT_INT(b); - MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b); - SKIP_BYTES(b, count * BYTES_PER_SPAN); - break; - } - case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc endShapeClip:dstOps]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc resetClip]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint rule = NEXT_INT(b); - jfloat extraAlpha = NEXT_FLOAT(b); - jint flags = NEXT_INT(b); - [mtlc setAlphaCompositeRule:rule extraAlpha:extraAlpha flags:flags]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jint xorPixel = NEXT_INT(b); - [mtlc setXorComposite:xorPixel]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE: - { - /* TODO: check whether something needs to be done here if we are moving out of XOR composite - commitEncodedCommands(); - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - [cbwrapper onComplete]; - - J2dTraceLn(J2D_TRACE_VERBOSE, - "RESET_COMPOSITE - Force commit earlier draw calls before RESET_COMPOSITE.");*/ - - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc resetComposite]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jdouble m00 = NEXT_DOUBLE(b); - jdouble m10 = NEXT_DOUBLE(b); - jdouble m01 = NEXT_DOUBLE(b); - jdouble m11 = NEXT_DOUBLE(b); - jdouble m02 = NEXT_DOUBLE(b); - jdouble m12 = NEXT_DOUBLE(b); - [mtlc setTransformM00:m00 M10:m10 M01:m01 M11:m11 M02:m02 M12:m12]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc resetTransform]; - break; - } - - // context-related ops - case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pSrc = NEXT_LONG(b); - jlong pDst = NEXT_LONG(b); - - if (mtlc != NULL) { - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - } - mtlc = [MTLContext setSurfacesEnv:env src:pSrc dst:pDst]; - dstOps = (BMTLSDOps *)jlong_to_ptr(pDst); - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pConfigInfo = NEXT_LONG(b); - MTLGraphicsConfigInfo *mtlInfo = - (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); - - if (mtlInfo == NULL) { - - } else { - MTLContext *newMtlc = mtlInfo->context; - if (newMtlc == NULL) { - - } else { - if (mtlc != NULL) { - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - } - mtlc = newMtlc; - dstOps = NULL; - } - } - break; - } - case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pData = NEXT_LONG(b); - BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData); - if (mtlsdo != NULL) { - CONTINUE_IF_NULL(mtlc); - MTLTR_FreeGlyphCaches(); - MTLSD_Delete(env, mtlsdo); - } - break; - } - case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pData = NEXT_LONG(b); - BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData); - if (mtlsdo != NULL) { - CONTINUE_IF_NULL(mtlc); - MTLSD_Delete(env, mtlsdo); - if (mtlsdo->privOps != NULL) { - free(mtlsdo->privOps); - } - } - break; - } - case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pConfigInfo = NEXT_LONG(b); - CONTINUE_IF_NULL(mtlc); - - if (mtlc != NULL) { - [mtlc.encoderManager endEncoder]; - } - - MTLGC_DestroyMTLGraphicsConfig(pConfigInfo); - - mtlc = NULL; - // dstOps = NULL; - break; - } - - case sun_java2d_pipe_BufferedOpCodes_SYNC: - { - CHECK_PREVIOUS_OP(MTL_OP_SYNC); - break; - } - - // special no-op (mainly used for achieving 8-byte alignment) - case sun_java2d_pipe_BufferedOpCodes_NOOP: - break; - - // paint-related ops - case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT: - { - CHECK_PREVIOUS_OP(MTL_OP_RESET_PAINT); - [mtlc resetPaint]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_COLOR: - { - CHECK_PREVIOUS_OP(MTL_OP_SET_COLOR); - jint pixel = NEXT_INT(b); - [mtlc setColorPaint:pixel]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jboolean useMask= NEXT_BOOLEAN(b); - jboolean cyclic = NEXT_BOOLEAN(b); - jdouble p0 = NEXT_DOUBLE(b); - jdouble p1 = NEXT_DOUBLE(b); - jdouble p3 = NEXT_DOUBLE(b); - jint pixel1 = NEXT_INT(b); - jint pixel2 = NEXT_INT(b); - [mtlc setGradientPaintUseMask:useMask - cyclic:cyclic - p0:p0 - p1:p1 - p3:p3 - pixel1:pixel1 - pixel2:pixel2]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jboolean useMask = NEXT_BOOLEAN(b); - jboolean linear = NEXT_BOOLEAN(b); - jint cycleMethod = NEXT_INT(b); - jint numStops = NEXT_INT(b); - jfloat p0 = NEXT_FLOAT(b); - jfloat p1 = NEXT_FLOAT(b); - jfloat p3 = NEXT_FLOAT(b); - void *fractions, *pixels; - fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); - pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); - [mtlc setLinearGradientPaint:useMask - linear:linear - cycleMethod:cycleMethod - numStops:numStops - p0:p0 - p1:p1 - p3:p3 - fractions:fractions - pixels:pixels]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jboolean useMask = NEXT_BOOLEAN(b); - jboolean linear = NEXT_BOOLEAN(b); - jint numStops = NEXT_INT(b); - jint cycleMethod = NEXT_INT(b); - jfloat m00 = NEXT_FLOAT(b); - jfloat m01 = NEXT_FLOAT(b); - jfloat m02 = NEXT_FLOAT(b); - jfloat m10 = NEXT_FLOAT(b); - jfloat m11 = NEXT_FLOAT(b); - jfloat m12 = NEXT_FLOAT(b); - jfloat focusX = NEXT_FLOAT(b); - void *fractions, *pixels; - fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); - pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); - [mtlc setRadialGradientPaint:useMask - linear:linear - cycleMethod:cycleMethod - numStops:numStops - m00:m00 - m01:m01 - m02:m02 - m10:m10 - m11:m11 - m12:m12 - focusX:focusX - fractions:fractions - pixels:pixels]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jboolean useMask= NEXT_BOOLEAN(b); - jboolean filter = NEXT_BOOLEAN(b); - jlong pSrc = NEXT_LONG(b); - jdouble xp0 = NEXT_DOUBLE(b); - jdouble xp1 = NEXT_DOUBLE(b); - jdouble xp3 = NEXT_DOUBLE(b); - jdouble yp0 = NEXT_DOUBLE(b); - jdouble yp1 = NEXT_DOUBLE(b); - jdouble yp3 = NEXT_DOUBLE(b); - [mtlc setTexturePaint:useMask - pSrcOps:pSrc - filter:filter - xp0:xp0 - xp1:xp1 - xp3:xp3 - yp0:yp0 - yp1:yp1 - yp3:yp3]; - break; - } - - // BufferedImageOp-related ops - case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pSrc = NEXT_LONG(b); - jboolean edgeZero = NEXT_BOOLEAN(b); - jint kernelWidth = NEXT_INT(b); - jint kernelHeight = NEXT_INT(b); - - BMTLSDOps * bmtlsdOps = (BMTLSDOps *)pSrc; - MTLConvolveOp * convolveOp = [[MTLConvolveOp alloc] init:edgeZero - kernelWidth:kernelWidth - kernelHeight:kernelHeight - srcWidth:bmtlsdOps->width - srcHeight:bmtlsdOps->height - kernel:b - device:mtlc.device - ]; - [mtlc setBufImgOp:convolveOp]; - SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat)); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc setBufImgOp:NULL]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pSrc = NEXT_LONG(b); - jboolean nonPremult = NEXT_BOOLEAN(b); - jint numFactors = 4; - unsigned char *scaleFactors = b; - unsigned char *offsets = (b + numFactors * sizeof(jfloat)); - MTLRescaleOp * rescaleOp = - [[MTLRescaleOp alloc] init:nonPremult factors:scaleFactors offsets:offsets]; - [mtlc setBufImgOp:rescaleOp]; - SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc setBufImgOp:NULL]; - break; - } - case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - jlong pSrc = NEXT_LONG(b); - jboolean nonPremult = NEXT_BOOLEAN(b); - jboolean shortData = NEXT_BOOLEAN(b); - jint numBands = NEXT_INT(b); - jint bandLength = NEXT_INT(b); - jint offset = NEXT_INT(b); - jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte); - void *tableValues = b; - - MTLLookupOp * lookupOp = [[MTLLookupOp alloc] init:nonPremult - shortData:shortData - numBands:numBands - bandLength:bandLength - offset:offset - tableValues:tableValues - device:mtlc.device]; - [mtlc setBufImgOp:lookupOp]; - SKIP_BYTES(b, numBands * bandLength * bytesPerElem); - break; - } - case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP: - { - CHECK_PREVIOUS_OP(MTL_OP_OTHER); - [mtlc setBufImgOp:NULL]; - break; - } - - default: - J2dRlsTraceLn1(J2D_TRACE_ERROR, - "MTLRenderQueue_flushBuffer: invalid opcode=%d", opcode); - return; - } - } - - if (mtlc != NULL) { - if (mtlPreviousOp == MTL_OP_MASK_OP) { - MTLVertexCache_DisableMaskCache(mtlc); - } - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - if (dstOps != NULL) { - MTLSDOps *dstMTLOps = (MTLSDOps *)dstOps->privOps; - MTLLayer *layer = (MTLLayer*)dstMTLOps->layer; - if (layer != NULL) { - [layer startDisplayLink]; - } - } - } - RESET_PREVIOUS_OP(); - } -} - -/** - * Returns a pointer to the "current" context, as set by the last SET_SURFACES - * or SET_SCRATCH_SURFACE operation. - */ -MTLContext * -MTLRenderQueue_GetCurrentContext() -{ - return mtlc; -} - -/** - * Returns a pointer to the "current" destination surface, as set by the last - * SET_SURFACES operation. - */ -BMTLSDOps * -MTLRenderQueue_GetCurrentDestination() -{ - return dstOps; -} - -/** - * commit earlier encoded commmands - * these would be rendered to the back-buffer - which is read in shader while rendering in XOR mode - */ -void commitEncodedCommands() { - [mtlc.encoderManager endEncoder]; - - MTLCommandBufferWrapper *cbwrapper = [mtlc pullCommandBufferWrapper]; - id <MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - [commandbuf waitUntilCompleted]; -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.h deleted file mode 100644 index 4ec9956305b..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLRenderer_h_Included -#define MTLRenderer_h_Included - -#include "sun_java2d_pipe_BufferedRenderPipe.h" -#include "MTLContext.h" -#include "MTLGraphicsConfig.h" -#import "MTLLayer.h" - -#define BYTES_PER_POLY_POINT \ - sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_POLY_POINT -#define BYTES_PER_SCANLINE \ - sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_SCANLINE -#define BYTES_PER_SPAN \ - sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_SPAN - -void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, - jint x1, jint y1, jint x2, jint y2); -void MTLRenderer_DrawPixel(MTLContext *mtlc, BMTLSDOps * dstOps, - jint x, jint y); -void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps, - jint x, jint y, jint w, jint h); -void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps, - jint nPoints, jint isClosed, - jint transX, jint transY, - jint *xPoints, jint *yPoints); -void MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps, - jint count, jint *scanlines); -void MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12, - jfloat lw21, jfloat lw12); -void MTLRenderer_DrawAAParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12, - jfloat lw21, jfloat lw12); -void MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, - jint x, jint y, jint w, jint h); -void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, - jint count, jint *spans); -void MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12); -void MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12); - -#endif /* MTLRenderer_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.m deleted file mode 100644 index 12eadeac7a5..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.m +++ /dev/null @@ -1,961 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <jlong.h> -#include <jni_util.h> -#include <math.h> - -#include "sun_java2d_metal_MTLRenderer.h" - -#include "MTLRenderer.h" -#include "MTLRenderQueue.h" -#include "MTLSurfaceData.h" -#include "MTLUtils.h" -#import "MTLLayer.h" - -/** - * Note: Some of the methods in this file apply a "magic number" - * translation to line segments. It is same as what we have in - * OGLrenderer. - * - * The "magic numbers" you see here have been empirically derived - * after testing on a variety of graphics hardware in order to find some - * reasonable middle ground between the two specifications. The general - * approach is to apply a fractional translation to vertices so that they - * hit pixel centers and therefore touch the same pixels as in our other - * pipelines. Emphasis was placed on finding values so that MTL lines with - * a slope of +/- 1 hit all the same pixels as our other (software) loops. - * The stepping in other diagonal lines rendered with MTL may deviate - * slightly from those rendered with our software loops, but the most - * important thing is that these magic numbers ensure that all MTL lines - * hit the same endpoints as our software loops. - * - * If you find it necessary to change any of these magic numbers in the - * future, just be sure that you test the changes across a variety of - * hardware to ensure consistent rendering everywhere. - */ - -void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1, jint x2, jint y2) { - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawLine: dest is null"); - return; - } - - J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawLine (x1=%d y1=%d x2=%d y2=%d), dst tex=%p", x1, y1, x2, y2, dstOps->pTexture); - - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps]; - if (mtlEncoder == nil) - return; - - // DrawLine implementation same as in OGLRenderer.c - struct Vertex verts[2]; - if (y1 == y2) { - // horizontal - float fx1 = (float)x1; - float fx2 = (float)x2; - float fy = ((float)y1) + 0.2f; - - if (x1 > x2) { - float t = fx1; fx1 = fx2; fx2 = t; - } - - verts[0].position[0] = fx1 + 0.2f; - verts[0].position[1] = fy; - verts[1].position[0] = fx2 + 1.2f; - verts[1].position[1] = fy; - } else if (x1 == x2) { - // vertical - float fx = ((float)x1) + 0.2f; - float fy1 = (float)y1; - float fy2 = (float)y2; - - if (y1 > y2) { - float t = fy1; fy1 = fy2; fy2 = t; - } - - verts[0].position[0] = fx; - verts[0].position[1] = fy1 + 0.2f; - verts[1].position[0] = fx; - verts[1].position[1] = fy2 + 1.2f; - } else { - // diagonal - float fx1 = (float)x1; - float fy1 = (float)y1; - float fx2 = (float)x2; - float fy2 = (float)y2; - - if (x1 < x2) { - fx1 += 0.2f; - fx2 += 1.0f; - } else { - fx1 += 0.8f; - fx2 -= 0.2f; - } - - if (y1 < y2) { - fy1 += 0.2f; - fy2 += 1.0f; - } else { - fy1 += 0.8f; - fy2 -= 0.2f; - } - verts[0].position[0] = fx1; - verts[0].position[1] = fy1; - verts[1].position[0] = fx2; - verts[1].position[1] = fy2; - } - - [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2]; -} - -void MTLRenderer_DrawPixel(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y) { - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPixel: dest is null"); - return; - } - - id<MTLTexture> dest = dstOps->pTexture; - J2dTraceLn3(J2D_TRACE_INFO, "MTLRenderer_DrawPixel (x=%d y=%d), dst tex=%p", x, y, dest); - - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps]; - if (mtlEncoder == nil) - return; - - // Translate each vertex by a fraction so - // that we hit pixel centers. - float fx = (float)x + 0.2f; - float fy = (float)y + 0.5f; - struct Vertex vert = {{fx, fy}}; - [mtlEncoder setVertexBytes:&vert length:sizeof(vert) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypePoint vertexStart:0 vertexCount:1]; -} - -void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h) { - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawRect: dest is null"); - return; - } - - id<MTLTexture> dest = dstOps->pTexture; - J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest); - - // TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1) - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps]; - if (mtlEncoder == nil) - return; - - // Translate each vertex by a fraction so - // that we hit pixel centers. - const int verticesCount = 5; - float fx = (float)x + 0.2f; - float fy = (float)y + 0.5f; - float fw = (float)w; - float fh = (float)h; - struct Vertex vertices[5] = { - {{fx, fy}}, - {{fx + fw, fy}}, - {{fx + fw, fy + fh}}, - {{fx, fy + fh}}, - {{fx, fy}}, - }; - [mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:verticesCount]; -} - -const int POLYLINE_BUF_SIZE = 64; - -NS_INLINE void fillVertex(struct Vertex * vertex, int x, int y) { - vertex->position[0] = x; - vertex->position[1] = y; -} - -void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps, - jint nPoints, jint isClosed, - jint transX, jint transY, - jint *xPoints, jint *yPoints) -{ - // Note that BufferedRenderPipe.drawPoly() has already rejected polys - // with nPoints<2, so we can be certain here that we have nPoints>=2. - if (xPoints == NULL || yPoints == NULL || nPoints < 2) { // just for insurance - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPoly: points array is empty"); - return; - } - - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPoly: dest is null"); - return; - } - - J2dTraceLn4(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: %d points, transX=%d, transY=%d, dst tex=%p", nPoints, transX, transY, dstOps->pTexture); - - __block struct { - struct Vertex verts[POLYLINE_BUF_SIZE]; - } pointsChunk; - - // We intend to submit draw commands in batches of POLYLINE_BUF_SIZE vertices at a time - // Subsequent batches need to be connected - so end point in one batch is repeated as first point in subsequent batch - // This inflates the total number of points by a factor of number of batches of size POLYLINE_BUF_SIZE - nPoints += (nPoints/POLYLINE_BUF_SIZE); - - jint prevX = *(xPoints++); - jint prevY = *(yPoints++); - const jint firstX = prevX; - const jint firstY = prevY; - while (nPoints > 0) { - const bool isLastChunk = nPoints <= POLYLINE_BUF_SIZE; - __block int chunkSize = isLastChunk ? nPoints : POLYLINE_BUF_SIZE; - - fillVertex(pointsChunk.verts, prevX + transX + 0.5f, prevY + transY + 0.5f); - J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: Point - (%1.2f, %1.2f)", prevX + transX + 0.5f, prevY + transY + 0.5f); - - for (int i = 1; i < chunkSize; i++) { - prevX = *(xPoints++); - prevY = *(yPoints++); - fillVertex(pointsChunk.verts + i, prevX + transX + 0.5f, prevY + transY + 0.5f); - J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: Point - (%1.2f, %1.2f)", prevX + transX + 0.5f,prevY + transY + 0.5f); - } - - bool drawCloseSegment = false; - if (isClosed && isLastChunk) { - if (chunkSize + 2 <= POLYLINE_BUF_SIZE) { - fillVertex(pointsChunk.verts + chunkSize, firstX + transX + 0.5f, firstY + transY + 0.5f); - J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: Point - (%1.2f, %1.2f)",firstX + transX + 0.5f, firstY + transY + 0.5f); - - ++chunkSize; - } else - drawCloseSegment = true; - } - - nPoints -= chunkSize; - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps]; - if (mtlEncoder == nil) - return; - - [mtlEncoder setVertexBytes:pointsChunk.verts length:sizeof(pointsChunk.verts) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:chunkSize]; - - if (drawCloseSegment) { - struct Vertex vertices[2] = { - {{prevX + transX + 0.5f, prevY + transY + 0.5f}}, - {{firstX + transX + 0.5f, firstY + transY + 0.5f}} - }; - - J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: last segment Point1 - (%1.2f, %1.2f)",prevX + transX + 0.5f, prevY + transY + 0.5f); - J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: last segment Point2 - (%1.2f, %1.2f)",firstX + transX + 0.5f, firstY + transY + 0.5f); - - [mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2]; - } - } -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLRenderer_drawPoly - (JNIEnv *env, jobject mtlr, - jintArray xpointsArray, jintArray ypointsArray, - jint nPoints, jboolean isClosed, - jint transX, jint transY) -{ - jint *xPoints, *yPoints; - - J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_drawPoly"); - - xPoints = (jint *) - (*env)->GetPrimitiveArrayCritical(env, xpointsArray, NULL); - if (xPoints != NULL) { - yPoints = (jint *) - (*env)->GetPrimitiveArrayCritical(env, ypointsArray, NULL); - if (yPoints != NULL) { - MTLContext *mtlc = MTLRenderQueue_GetCurrentContext(); - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - - MTLRenderer_DrawPoly(mtlc, dstOps, - nPoints, isClosed, - transX, transY, - xPoints, yPoints); - if (mtlc != NULL) { - RESET_PREVIOUS_OP(); - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - } - - (*env)->ReleasePrimitiveArrayCritical(env, ypointsArray, yPoints, - JNI_ABORT); - } - (*env)->ReleasePrimitiveArrayCritical(env, xpointsArray, xPoints, - JNI_ABORT); - } -} - -const int SCANLINE_MAX_VERTEX_SIZE = 4096; -const int VERTEX_STRUCT_SIZE = 8; -const int NUM_OF_VERTICES_PER_SCANLINE = 2; - -void -MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps, - jint scanlineCount, jint *scanlines) -{ - - J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawScanlines (scanlineCount=%d), dst tex=%p", scanlineCount, dstOps->pTexture); - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawScanlines: dest is null"); - return; - } - RETURN_IF_NULL(scanlines); - int vertexSize = NUM_OF_VERTICES_PER_SCANLINE - * scanlineCount * VERTEX_STRUCT_SIZE; - J2dTraceLn1(J2D_TRACE_INFO, "MTLRenderer_DrawScanlines: Total vertex size : %d", vertexSize); - if (vertexSize == 0) return; - - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps]; - - if (mtlEncoder == nil) return; - - if (vertexSize <= SCANLINE_MAX_VERTEX_SIZE) { - struct Vertex verts[NUM_OF_VERTICES_PER_SCANLINE * scanlineCount]; - - for (int j = 0, i = 0; j < scanlineCount; j++) { - // Translate each vertex by a fraction so - // that we hit pixel centers. - float x1 = ((float)*(scanlines++)) + 0.2f; - float x2 = ((float)*(scanlines++)) + 1.2f; - float y = ((float)*(scanlines++)) + 0.5f; - struct Vertex v1 = {{x1, y}}; - struct Vertex v2 = {{x2, y}}; - verts[i++] = v1; - verts[i++] = v2; - } - - [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 - vertexCount:NUM_OF_VERTICES_PER_SCANLINE * scanlineCount]; - } else { - int remainingScanlineCount = vertexSize; - do { - if (remainingScanlineCount > SCANLINE_MAX_VERTEX_SIZE) { - struct Vertex verts[SCANLINE_MAX_VERTEX_SIZE/ VERTEX_STRUCT_SIZE]; - - for (int j = 0, i = 0; j < (SCANLINE_MAX_VERTEX_SIZE / (VERTEX_STRUCT_SIZE * 2)); j++) { - // Translate each vertex by a fraction so - // that we hit pixel centers. - float x1 = ((float)*(scanlines++)) + 0.2f; - float x2 = ((float)*(scanlines++)) + 1.2f; - float y = ((float)*(scanlines++)) + 0.5f; - struct Vertex v1 = {{x1, y}}; - struct Vertex v2 = {{x2, y}}; - verts[i++] = v1; - verts[i++] = v2; - } - - [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 - vertexCount:(SCANLINE_MAX_VERTEX_SIZE / VERTEX_STRUCT_SIZE)]; - remainingScanlineCount -= SCANLINE_MAX_VERTEX_SIZE; - } else { - struct Vertex verts[remainingScanlineCount / VERTEX_STRUCT_SIZE]; - - for (int j = 0, i = 0; j < (remainingScanlineCount / (VERTEX_STRUCT_SIZE * 2)); j++) { - // Translate each vertex by a fraction so - // that we hit pixel centers. - float x1 = ((float)*(scanlines++)) + 0.2f; - float x2 = ((float)*(scanlines++)) + 1.2f; - float y = ((float)*(scanlines++)) + 0.5f; - struct Vertex v1 = {{x1, y}}; - struct Vertex v2 = {{x2, y}}; - verts[i++] = v1; - verts[i++] = v2; - } - - [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 - vertexCount:(remainingScanlineCount / VERTEX_STRUCT_SIZE)]; - remainingScanlineCount -= remainingScanlineCount; - } - J2dTraceLn1(J2D_TRACE_INFO, - "MTLRenderer_DrawScanlines: Remaining vertex size %d", remainingScanlineCount); - } while (remainingScanlineCount != 0); - } -} - -void -MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillRect"); - - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillRect: current dest is null"); - return; - } - - struct Vertex verts[QUAD_VERTEX_COUNT] = { - { {x, y}}, - { {x, y+h}}, - { {x+w, y}}, - { {x+w, y+h} - }}; - - - id<MTLTexture> dest = dstOps->pTexture; - J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_FillRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest); - - // Encode render command. - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps]; - if (mtlEncoder == nil) - return; - - [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT]; -} - -void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillSpans"); - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillSpans: dest is null"); - return; - } - - // MTLRenderCommandEncoder setVertexBytes usage is recommended if the data is of 4KB. - - // We use a buffer that closely matches the 4KB limit size - // This buffer is resued multiple times to encode draw calls of a triangle list - // NOTE : Due to nature of *spans data - it is not possible to use triangle strip. - // We use triangle list to draw spans - - // Destination texture to which render commands are encoded - id<MTLTexture> dest = dstOps->pTexture; - id<MTLTexture> destAA = nil; - BOOL isDestOpaque = dstOps->isOpaque; - if (mtlc.clip.stencilMaskGenerationInProgress == JNI_TRUE) { - dest = dstOps->pStencilData; - isDestOpaque = NO; - } - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dest isDstOpaque:isDestOpaque]; - if (mtlEncoder == nil) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillSpans: mtlEncoder is nil"); - return; - } - - // This is the max no of vertices (of struct Vertex - 8 bytes) we can accomodate in 4KB - const int TOTAL_VERTICES_IN_BLOCK = 510; - struct Vertex vertexList[TOTAL_VERTICES_IN_BLOCK]; // a total of 170 triangles ==> 85 spans - - jfloat shapeX1 = mtlc.clip.shapeX; - jfloat shapeY1 = mtlc.clip.shapeY; - jfloat shapeX2 = (mtlc.clip.shapeWidth > 0)? shapeX1 + mtlc.clip.shapeWidth : 0; - jfloat shapeY2 = (mtlc.clip.shapeHeight > 0)? shapeY1 + mtlc.clip.shapeHeight : 0; - - int counter = 0; - for (int i = 0; i < spanCount; i++) { - jfloat x1 = *(spans++); - jfloat y1 = *(spans++); - jfloat x2 = *(spans++); - jfloat y2 = *(spans++); - - if (mtlc.clip.stencilMaskGenerationInProgress == JNI_TRUE) { - if (shapeX1 > x1) shapeX1 = x1; - if (shapeY1 > y1) shapeY1 = y1; - if (shapeX2 < x2) shapeX2 = x2; - if (shapeY2 < y2) shapeY2 = y2; - } - - struct Vertex verts[6] = { - {{x1, y1}}, - {{x1, y2}}, - {{x2, y1}}, - - {{x1, y2}}, - {{x2, y1}}, - {{x2, y2} - }}; - - memcpy(&vertexList[counter], &verts, sizeof(verts)); - counter += 6; - - // If vertexList buffer full - if (counter % TOTAL_VERTICES_IN_BLOCK == 0) { - [mtlEncoder setVertexBytes:vertexList length:sizeof(vertexList) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:TOTAL_VERTICES_IN_BLOCK]; - counter = 0; - } - } - - // Draw triangles using remaining vertices if any - if (counter != 0) { - [mtlEncoder setVertexBytes:vertexList length:sizeof(vertexList) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:counter]; - } - - if (mtlc.clip.stencilMaskGenerationInProgress == JNI_TRUE) { - if (shapeX1 < 0) shapeX1 = 0; - if (shapeY1 < 0) shapeY1 = 0; - if (shapeX1 > dest.width) shapeX1 = dest.width; - if (shapeY1 > dest.height) shapeY1 = dest.height; - if (shapeX2 < 0) shapeX2 = 0; - if (shapeY2 < 0) shapeY2 = 0; - if (shapeX2 > dest.width) shapeX2 = dest.width; - if (shapeY2 > dest.height) shapeY2 = dest.height; - - mtlc.clip.shapeX = (NSUInteger) shapeX1; - mtlc.clip.shapeY = (NSUInteger) shapeY1; - mtlc.clip.shapeWidth = (NSUInteger) (shapeX2 - shapeX1); - mtlc.clip.shapeHeight = (NSUInteger) (shapeY2 - shapeY1); - } -} - -void -MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12) -{ - - if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillParallelogram: current dest is null"); - return; - } - - id<MTLTexture> dest = dstOps->pTexture; - J2dTraceLn7(J2D_TRACE_INFO, - "MTLRenderer_FillParallelogram" - "(x=%6.2f y=%6.2f " - "dx1=%6.2f dy1=%6.2f " - "dx2=%6.2f dy2=%6.2f dst tex=%p)", - fx11, fy11, - dx21, dy21, - dx12, dy12, dest); - - struct Vertex verts[QUAD_VERTEX_COUNT] = { - { {fx11, fy11}}, - { {fx11+dx21, fy11+dy21}}, - { {fx11+dx12, fy11+dy12}}, - { {fx11 + dx21 + dx12, fy11+ dy21 + dy12} - }}; - - // Encode render command. - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];; - - if (mtlEncoder == nil) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillParallelogram: error creating MTLRenderCommandEncoder."); - return; - } - - [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT]; -} - -void -MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12, - jfloat lwr21, jfloat lwr12) -{ - // dx,dy for line width in the "21" and "12" directions. - jfloat ldx21 = dx21 * lwr21; - jfloat ldy21 = dy21 * lwr21; - jfloat ldx12 = dx12 * lwr12; - jfloat ldy12 = dy12 * lwr12; - - // calculate origin of the outer parallelogram - jfloat ox11 = fx11 - (ldx21 + ldx12) / 2.0f; - jfloat oy11 = fy11 - (ldy21 + ldy12) / 2.0f; - - J2dTraceLn8(J2D_TRACE_INFO, - "MTLRenderer_DrawParallelogram" - "(x=%6.2f y=%6.2f " - "dx1=%6.2f dy1=%6.2f lwr1=%6.2f " - "dx2=%6.2f dy2=%6.2f lwr2=%6.2f)", - fx11, fy11, - dx21, dy21, lwr21, - dx12, dy12, lwr12); - - - // Only need to generate 4 quads if the interior still - // has a hole in it (i.e. if the line width ratio was - // less than 1.0) - if (lwr21 < 1.0f && lwr12 < 1.0f) { - - // Note: "TOP", "BOTTOM", "LEFT" and "RIGHT" here are - // relative to whether the dxNN variables are positive - // and negative. The math works fine regardless of - // their signs, but for conceptual simplicity the - // comments will refer to the sides as if the dxNN - // were all positive. "TOP" and "BOTTOM" segments - // are defined by the dxy21 deltas. "LEFT" and "RIGHT" - // segments are defined by the dxy12 deltas. - - // Each segment includes its starting corner and comes - // to just short of the following corner. Thus, each - // corner is included just once and the only lengths - // needed are the original parallelogram delta lengths - // and the "line width deltas". The sides will cover - // the following relative territories: - // - // T T T T T R - // L R - // L R - // L R - // L R - // L B B B B B - - // Every segment is drawn as a filled Parallelogram quad - // Each quad is encoded using two triangles - // For 4 segments - there are 8 triangles in total - // Each triangle has 3 vertices - const int TOTAL_VERTICES = 8 * 3; - struct Vertex vertexList[TOTAL_VERTICES]; - int i = 0; - - // TOP segment, to left side of RIGHT edge - // "width" of original pgram, "height" of hor. line size - fx11 = ox11; - fy11 = oy11; - - fillVertex(vertexList + (i++), fx11, fy11); - fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21); - fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12); - - fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12); - fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12); - fillVertex(vertexList + (i++), fx11, fy11); - - // RIGHT segment, to top of BOTTOM edge - // "width" of vert. line size , "height" of original pgram - fx11 = ox11 + dx21; - fy11 = oy11 + dy21; - fillVertex(vertexList + (i++), fx11, fy11); - fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21); - fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12); - - fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12); - fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12); - fillVertex(vertexList + (i++), fx11, fy11); - - // BOTTOM segment, from right side of LEFT edge - // "width" of original pgram, "height" of hor. line size - fx11 = ox11 + dx12 + ldx21; - fy11 = oy11 + dy12 + ldy21; - fillVertex(vertexList + (i++), fx11, fy11); - fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21); - fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12); - - fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12); - fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12); - fillVertex(vertexList + (i++), fx11, fy11); - - // LEFT segment, from bottom of TOP edge - // "width" of vert. line size , "height" of inner pgram - fx11 = ox11 + ldx12; - fy11 = oy11 + ldy12; - fillVertex(vertexList + (i++), fx11, fy11); - fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21); - fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12); - - fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12); - fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12); - fillVertex(vertexList + (i++), fx11, fy11); - - // Encode render command. - id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps]; - - if (mtlEncoder == nil) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawParallelogram: error creating MTLRenderCommandEncoder."); - return; - } - - [mtlEncoder setVertexBytes:vertexList length:sizeof(vertexList) atIndex:MeshVertexBuffer]; - [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:TOTAL_VERTICES]; - } else { - // The line width ratios were large enough to consume - // the entire hole in the middle of the parallelogram - // so we can just issue one large quad for the outer - // parallelogram. - dx21 += ldx21; - dy21 += ldy21; - dx12 += ldx12; - dy12 += ldy12; - MTLRenderer_FillParallelogram(mtlc, dstOps, ox11, oy11, dx21, dy21, dx12, dy12); - } -} - -static struct AAVertex aaVertices[6]; -static jint vertexCacheIndex = 0; - -#define AA_ADD_VERTEX(OU, OV, IU, IV, DX, DY) \ - do { \ - struct AAVertex *v = &aaVertices[vertexCacheIndex++]; \ - v->otxtpos[0] = OU; \ - v->otxtpos[1] = OV; \ - v->itxtpos[0] = IU; \ - v->itxtpos[1] = IV; \ - v->position[0]= DX; \ - v->position[1] = DY; \ - } while (0) - -#define AA_ADD_TRIANGLES(ou11, ov11, iu11, iv11, ou21, ov21, iu21, iv21, ou22, ov22, iu22, iv22, ou12, ov12, iu12, iv12, DX1, DY1, DX2, DY2) \ - do { \ - AA_ADD_VERTEX(ou11, ov11, iu11, iv11, DX1, DY1); \ - AA_ADD_VERTEX(ou21, ov21, iu21, iv21, DX2, DY1); \ - AA_ADD_VERTEX(ou22, ov22, iu22, iv22, DX2, DY2); \ - AA_ADD_VERTEX(ou22, ov22, iu22, iv22, DX2, DY2); \ - AA_ADD_VERTEX(ou12, ov12, iu12, iv12, DX1, DY2); \ - AA_ADD_VERTEX(ou11, ov11, iu11, iv11, DX1, DY1); \ - } while (0) - -#define ADJUST_PGRAM(V1, DV, V2) \ - do { \ - if ((DV) >= 0) { \ - (V2) += (DV); \ - } else { \ - (V1) += (DV); \ - } \ - } while (0) - -// Invert the following transform: -// DeltaT(0, 0) == (0, 0) -// DeltaT(1, 0) == (DX1, DY1) -// DeltaT(0, 1) == (DX2, DY2) -// DeltaT(1, 1) == (DX1+DX2, DY1+DY2) -// TM00 = DX1, TM01 = DX2, (TM02 = X11) -// TM10 = DY1, TM11 = DY2, (TM12 = Y11) -// Determinant = TM00*TM11 - TM01*TM10 -// = DX1*DY2 - DX2*DY1 -// Inverse is: -// IM00 = TM11/det, IM01 = -TM01/det -// IM10 = -TM10/det, IM11 = TM00/det -// IM02 = (TM01 * TM12 - TM11 * TM02) / det, -// IM12 = (TM10 * TM02 - TM00 * TM12) / det, - -#define DECLARE_MATRIX(MAT) \ - jfloat MAT ## 00, MAT ## 01, MAT ## 02, MAT ## 10, MAT ## 11, MAT ## 12 - -#define GET_INVERTED_MATRIX(MAT, X11, Y11, DX1, DY1, DX2, DY2, RET_CODE) \ - do { \ - jfloat det = DX1*DY2 - DX2*DY1; \ - if (det == 0) { \ - RET_CODE; \ - } \ - MAT ## 00 = DY2/det; \ - MAT ## 01 = -DX2/det; \ - MAT ## 10 = -DY1/det; \ - MAT ## 11 = DX1/det; \ - MAT ## 02 = (DX2 * Y11 - DY2 * X11) / det; \ - MAT ## 12 = (DY1 * X11 - DX1 * Y11) / det; \ - } while (0) - -#define TRANSFORM(MAT, TX, TY, X, Y) \ - do { \ - TX = (X) * MAT ## 00 + (Y) * MAT ## 01 + MAT ## 02; \ - TY = (X) * MAT ## 10 + (Y) * MAT ## 11 + MAT ## 12; \ - } while (0) - -void -MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12) -{ - DECLARE_MATRIX(om); - // parameters for parallelogram bounding box - jfloat bx11, by11, bx22, by22; - // parameters for uv texture coordinates of parallelogram corners - jfloat ou11, ov11, ou12, ov12, ou21, ov21, ou22, ov22; - - J2dTraceLn6(J2D_TRACE_INFO, - "MTLRenderer_FillAAParallelogram " - "(x=%6.2f y=%6.2f " - "dx1=%6.2f dy1=%6.2f " - "dx2=%6.2f dy2=%6.2f)", - fx11, fy11, - dx21, dy21, - dx12, dy12); - - RETURN_IF_NULL(mtlc); - RETURN_IF_NULL(dstOps); - - GET_INVERTED_MATRIX(om, fx11, fy11, dx21, dy21, dx12, dy12, - return); - - bx11 = bx22 = fx11; - by11 = by22 = fy11; - ADJUST_PGRAM(bx11, dx21, bx22); - ADJUST_PGRAM(by11, dy21, by22); - ADJUST_PGRAM(bx11, dx12, bx22); - ADJUST_PGRAM(by11, dy12, by22); - bx11 = (jfloat) floor(bx11); - by11 = (jfloat) floor(by11); - bx22 = (jfloat) ceil(bx22); - by22 = (jfloat) ceil(by22); - - TRANSFORM(om, ou11, ov11, bx11, by11); - TRANSFORM(om, ou21, ov21, bx22, by11); - TRANSFORM(om, ou12, ov12, bx11, by22); - TRANSFORM(om, ou22, ov22, bx22, by22); - - id<MTLRenderCommandEncoder> encoder = - [mtlc.encoderManager getAAShaderRenderEncoder:dstOps]; - - AA_ADD_TRIANGLES(ou11, ov11, 5.f, 5.f, ou21, ov21, 6.f, 5.f, ou22, ov22, 6.f, 6.f, ou12, ov12, 5.f, 5.f, bx11, by11, bx22, by22); - [encoder setVertexBytes:aaVertices length:sizeof(aaVertices) atIndex:MeshVertexBuffer]; - [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; - vertexCacheIndex = 0; -} - -void -MTLRenderer_FillAAParallelogramInnerOuter(MTLContext *mtlc, MTLSDOps *dstOps, - jfloat ox11, jfloat oy11, - jfloat ox21, jfloat oy21, - jfloat ox12, jfloat oy12, - jfloat ix11, jfloat iy11, - jfloat ix21, jfloat iy21, - jfloat ix12, jfloat iy12) -{ - DECLARE_MATRIX(om); - DECLARE_MATRIX(im); - // parameters for parallelogram bounding box - jfloat bx11, by11, bx22, by22; - // parameters for uv texture coordinates of outer parallelogram corners - jfloat ou11, ov11, ou12, ov12, ou21, ov21, ou22, ov22; - // parameters for uv texture coordinates of inner parallelogram corners - jfloat iu11, iv11, iu12, iv12, iu21, iv21, iu22, iv22; - - RETURN_IF_NULL(mtlc); - RETURN_IF_NULL(dstOps); - - GET_INVERTED_MATRIX(im, ix11, iy11, ix21, iy21, ix12, iy12, - // inner parallelogram is degenerate - // therefore it encloses no area - // fill outer - MTLRenderer_FillAAParallelogram(mtlc, dstOps, - ox11, oy11, - ox21, oy21, - ox12, oy12); - return); - GET_INVERTED_MATRIX(om, ox11, oy11, ox21, oy21, ox12, oy12, - return); - - bx11 = bx22 = ox11; - by11 = by22 = oy11; - ADJUST_PGRAM(bx11, ox21, bx22); - ADJUST_PGRAM(by11, oy21, by22); - ADJUST_PGRAM(bx11, ox12, bx22); - ADJUST_PGRAM(by11, oy12, by22); - bx11 = (jfloat) floor(bx11); - by11 = (jfloat) floor(by11); - bx22 = (jfloat) ceil(bx22); - by22 = (jfloat) ceil(by22); - - TRANSFORM(om, ou11, ov11, bx11, by11); - TRANSFORM(om, ou21, ov21, bx22, by11); - TRANSFORM(om, ou12, ov12, bx11, by22); - TRANSFORM(om, ou22, ov22, bx22, by22); - - TRANSFORM(im, iu11, iv11, bx11, by11); - TRANSFORM(im, iu21, iv21, bx22, by11); - TRANSFORM(im, iu12, iv12, bx11, by22); - TRANSFORM(im, iu22, iv22, bx22, by22); - - id<MTLRenderCommandEncoder> encoder = - [mtlc.encoderManager getAAShaderRenderEncoder:dstOps]; - - AA_ADD_TRIANGLES(ou11, ov11, iu11, iv11, ou21, ov21, iu21, iv21, ou22, ov22, iu22, iv22, ou12, ov12, iu12, iv12, bx11, by11, bx22, by22); - [encoder setVertexBytes:aaVertices length:sizeof(aaVertices) atIndex:MeshVertexBuffer]; - [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; - vertexCacheIndex = 0; -} - -void -MTLRenderer_DrawAAParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps, - jfloat fx11, jfloat fy11, - jfloat dx21, jfloat dy21, - jfloat dx12, jfloat dy12, - jfloat lwr21, jfloat lwr12) -{ - // dx,dy for line width in the "21" and "12" directions. - jfloat ldx21, ldy21, ldx12, ldy12; - // parameters for "outer" parallelogram - jfloat ofx11, ofy11, odx21, ody21, odx12, ody12; - // parameters for "inner" parallelogram - jfloat ifx11, ify11, idx21, idy21, idx12, idy12; - - J2dTraceLn8(J2D_TRACE_INFO, - "MTLRenderer_DrawAAParallelogram " - "(x=%6.2f y=%6.2f " - "dx1=%6.2f dy1=%6.2f lwr1=%6.2f " - "dx2=%6.2f dy2=%6.2f lwr2=%6.2f)", - fx11, fy11, - dx21, dy21, lwr21, - dx12, dy12, lwr12); - - RETURN_IF_NULL(mtlc); - RETURN_IF_NULL(dstOps); - - // calculate true dx,dy for line widths from the "line width ratios" - ldx21 = dx21 * lwr21; - ldy21 = dy21 * lwr21; - ldx12 = dx12 * lwr12; - ldy12 = dy12 * lwr12; - - // calculate coordinates of the outer parallelogram - ofx11 = fx11 - (ldx21 + ldx12) / 2.0f; - ofy11 = fy11 - (ldy21 + ldy12) / 2.0f; - odx21 = dx21 + ldx21; - ody21 = dy21 + ldy21; - odx12 = dx12 + ldx12; - ody12 = dy12 + ldy12; - - // Only process the inner parallelogram if the line width ratio - // did not consume the entire interior of the parallelogram - // (i.e. if the width ratio was less than 1.0) - if (lwr21 < 1.0f && lwr12 < 1.0f) { - // calculate coordinates of the inner parallelogram - ifx11 = fx11 + (ldx21 + ldx12) / 2.0f; - ify11 = fy11 + (ldy21 + ldy12) / 2.0f; - idx21 = dx21 - ldx21; - idy21 = dy21 - ldy21; - idx12 = dx12 - ldx12; - idy12 = dy12 - ldy12; - - MTLRenderer_FillAAParallelogramInnerOuter(mtlc, dstOps, - ofx11, ofy11, - odx21, ody21, - odx12, ody12, - ifx11, ify11, - idx21, idy21, - idx12, idy12); - } else { - MTLRenderer_FillAAParallelogram(mtlc, dstOps, - ofx11, ofy11, - odx21, ody21, - odx12, ody12); - } -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.h deleted file mode 100644 index 506d8f1cd58..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLSamplerManager_h_Included -#define MTLSamplerManager_h_Included - -#import <Metal/Metal.h> - -#include "RenderOptions.h" - -@class MTLContex; - - -@interface MTLSamplerManager : NSObject -- (id _Nonnull)initWithDevice:(_Nonnull id<MTLDevice>) device; -- (void)dealloc; - -- (void) setSamplerWithEncoder:(_Nonnull id<MTLRenderCommandEncoder>) encoder - interpolation:(int) interpolation - repeat:(bool) repeat; -@end - -#endif // MTLSamplerManager_h_Included diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.m deleted file mode 100644 index f3f6db66dba..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSamplerManager.m +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "MTLSamplerManager.h" -#include "MTLContext.h" -#include "sun_java2d_SunGraphics2D.h" -#import "common.h" - -@implementation MTLSamplerManager { - id<MTLSamplerState> _samplerNearestClamp; - id<MTLSamplerState> _samplerLinearClamp; - id<MTLSamplerState> _samplerNearestRepeat; - id<MTLSamplerState> _samplerLinearRepeat; -} - -- (id _Nonnull)initWithDevice:(id<MTLDevice>) device { - self = [super init]; - if (self) { - MTLSamplerDescriptor *samplerDescriptor = [[MTLSamplerDescriptor new] autorelease]; - - samplerDescriptor.rAddressMode = MTLSamplerAddressModeClampToEdge; - samplerDescriptor.sAddressMode = MTLSamplerAddressModeClampToEdge; - samplerDescriptor.tAddressMode = MTLSamplerAddressModeClampToEdge; - - samplerDescriptor.minFilter = MTLSamplerMinMagFilterNearest; - samplerDescriptor.magFilter = MTLSamplerMinMagFilterNearest; - _samplerNearestClamp = [device newSamplerStateWithDescriptor:samplerDescriptor]; - - samplerDescriptor.minFilter = MTLSamplerMinMagFilterLinear; - samplerDescriptor.magFilter = MTLSamplerMinMagFilterLinear; - _samplerLinearClamp = [device newSamplerStateWithDescriptor:samplerDescriptor]; - - samplerDescriptor.rAddressMode = MTLSamplerAddressModeRepeat; - samplerDescriptor.sAddressMode = MTLSamplerAddressModeRepeat; - samplerDescriptor.tAddressMode = MTLSamplerAddressModeRepeat; - - samplerDescriptor.minFilter = MTLSamplerMinMagFilterNearest; - samplerDescriptor.magFilter = MTLSamplerMinMagFilterNearest; - _samplerNearestRepeat = [device newSamplerStateWithDescriptor:samplerDescriptor]; - - samplerDescriptor.minFilter = MTLSamplerMinMagFilterLinear; - samplerDescriptor.magFilter = MTLSamplerMinMagFilterLinear; - _samplerLinearRepeat = [device newSamplerStateWithDescriptor:samplerDescriptor]; - } - return self; -} - -- (void) setSamplerWithEncoder:(id<MTLRenderCommandEncoder>) encoder - interpolation:(int) interpolation - repeat:(bool) repeat { - id<MTLSamplerState> sampler; - if (repeat) { - sampler = interpolation == INTERPOLATION_BILINEAR ? _samplerLinearRepeat : _samplerNearestRepeat; - } else { - sampler = interpolation == INTERPOLATION_BILINEAR ? _samplerLinearClamp : _samplerNearestClamp; - } - [encoder setFragmentSamplerState:sampler atIndex:0]; -} - -- (void)dealloc { - [_samplerNearestClamp release]; - [_samplerLinearClamp release]; - [_samplerNearestRepeat release]; - [_samplerLinearRepeat release]; - [super dealloc]; -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.h deleted file mode 100644 index ee12bf564bf..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLStencilManager_h_Included -#define MTLStencilManager_h_Included - -#import <Metal/Metal.h> - -#include "RenderOptions.h" - -@class MTLContex; - - -@interface MTLStencilManager : NSObject -- (id _Nonnull)initWithDevice:(_Nonnull id<MTLDevice>) device; -- (void)dealloc; -@property (readonly) _Nonnull id<MTLDepthStencilState> stencilState; -@property (readonly) _Nonnull id<MTLDepthStencilState> genStencilState; -@end - -#endif // MTLSamplerManager_h_Included diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.m deleted file mode 100644 index d11ff891705..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLStencilManager.m +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "MTLStencilManager.h" -//#include "MTLContext.h" -//#include "sun_java2d_SunGraphics2D.h" -//#import "common.h" - -@implementation MTLStencilManager { - id<MTLDepthStencilState> _stencilState; - id<MTLDepthStencilState> _genStencilState; -} - -@synthesize stencilState = _stencilState; -@synthesize genStencilState = _genStencilState; - -- (id _Nonnull)initWithDevice:(id<MTLDevice>) device { - self = [super init]; - if (self) { - MTLDepthStencilDescriptor* stencilDescriptor; - stencilDescriptor = [[MTLDepthStencilDescriptor new] autorelease]; - stencilDescriptor.frontFaceStencil.stencilCompareFunction = MTLCompareFunctionEqual; - stencilDescriptor.frontFaceStencil.stencilFailureOperation = MTLStencilOperationKeep; - - // TODO : backFaceStencil can be set to nil if all primitives are drawn as front-facing primitives - // currently, fill parallelogram uses back-facing primitive drawing - that needs to be changed. - // Once that part is changed, set backFaceStencil to nil - //stencilDescriptor.backFaceStencil = nil; - - stencilDescriptor.backFaceStencil.stencilCompareFunction = MTLCompareFunctionEqual; - stencilDescriptor.backFaceStencil.stencilFailureOperation = MTLStencilOperationKeep; - _stencilState = [device newDepthStencilStateWithDescriptor:stencilDescriptor]; - - MTLDepthStencilDescriptor* genStencilDescriptor; - genStencilDescriptor = [[MTLDepthStencilDescriptor new] autorelease]; - genStencilDescriptor.backFaceStencil.stencilCompareFunction = MTLCompareFunctionAlways; - genStencilDescriptor.backFaceStencil.depthStencilPassOperation = MTLStencilOperationReplace; - genStencilDescriptor.frontFaceStencil.stencilCompareFunction = MTLCompareFunctionAlways; - genStencilDescriptor.frontFaceStencil.depthStencilPassOperation = MTLStencilOperationReplace; - _genStencilState = [device newDepthStencilStateWithDescriptor:genStencilDescriptor]; - } - return self; -} - -- (void)dealloc { - [_stencilState release]; - [super dealloc]; -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.h deleted file mode 100644 index d8ee2076a48..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLSurfaceData_h_Included -#define MTLSurfaceData_h_Included - -#import "MTLSurfaceDataBase.h" -#import "MTLGraphicsConfig.h" -#import "AWTWindow.h" -#import "MTLLayer.h" - -/** - * The MTLSDOps structure contains the MTL-specific information for a given - * MTLSurfaceData. It is referenced by the native MTLSDOps structure. - */ -typedef struct _MTLSDOps { - AWTView *peerData; - MTLLayer *layer; - jint argb[4]; // background clear color - MTLGraphicsConfigInfo *configInfo; -} MTLSDOps; - -// debug-method -NSString * getSurfaceDescription(const BMTLSDOps * bmtlsdOps); - -#endif /* MTLSurfaceData_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.m deleted file mode 100644 index 129ba99adcc..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.m +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#import <stdlib.h> - -#import "sun_java2d_metal_MTLSurfaceData.h" - -#import "jni_util.h" -#import "MTLGraphicsConfig.h" -#import "MTLSurfaceData.h" -#include "jlong.h" - -jboolean MTLSD_InitMTLWindow(JNIEnv *env, BMTLSDOps *bmtlsdo); -void MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *bmtlsdo, jint w, jint h); - -static jboolean MTLSurfaceData_initTexture(BMTLSDOps *bmtlsdo, jboolean isOpaque, jboolean rtt, jint width, jint height) { - @autoreleasepool { - if (bmtlsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: ops are null"); - return JNI_FALSE; - } - if (width <= 0 || height <= 0) { - J2dRlsTraceLn2(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: texture dimensions is incorrect, w=%d, h=%d", width, height); - return JNI_FALSE; - } - - MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps; - - if (mtlsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: MTLSDOps are null"); - return JNI_FALSE; - } - if (mtlsdo->configInfo == NULL || mtlsdo->configInfo->context == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: MTLSDOps wasn't initialized (context is null)"); - return JNI_FALSE; - } - - MTLContext* ctx = mtlsdo->configInfo->context; - - width = (width <= MTL_GPU_FAMILY_MAC_TXT_SIZE) ? width : 0; - height = (height <= MTL_GPU_FAMILY_MAC_TXT_SIZE) ? height : 0; - - J2dTraceLn3(J2D_TRACE_VERBOSE, " desired texture dimensions: w=%d h=%d max=%d", - width, height, MTL_GPU_FAMILY_MAC_TXT_SIZE); - - // if either dimension is 0, we cannot allocate a texture with the - // requested dimensions - if ((width == 0 || height == 0)) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: texture dimensions too large"); - return JNI_FALSE; - } - - MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm width: width height: height mipmapped: NO]; - textureDescriptor.usage = MTLTextureUsageUnknown; - textureDescriptor.storageMode = MTLStorageModePrivate; - bmtlsdo->pTexture = [ctx.device newTextureWithDescriptor: textureDescriptor]; - - MTLTextureDescriptor *stencilDataDescriptor = - [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Uint width:width height:height mipmapped:NO]; - stencilDataDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; - stencilDataDescriptor.storageMode = MTLStorageModePrivate; - bmtlsdo->pStencilData = [ctx.device newTextureWithDescriptor:stencilDataDescriptor]; - - MTLTextureDescriptor *stencilTextureDescriptor = - [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatStencil8 width:width height:height mipmapped:NO]; - stencilTextureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite; - stencilTextureDescriptor.storageMode = MTLStorageModePrivate; - bmtlsdo->pStencilTexture = [ctx.device newTextureWithDescriptor:stencilTextureDescriptor]; - bmtlsdo->isOpaque = isOpaque; - bmtlsdo->width = width; - bmtlsdo->height = height; - bmtlsdo->drawableType = rtt ? MTLSD_RT_TEXTURE : MTLSD_TEXTURE; - - J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLSurfaceData_initTexture: w=%d h=%d bp=%p [tex=%p] opaque=%d rtt=%d", width, height, bmtlsdo, bmtlsdo->pTexture, isOpaque, rtt); - return JNI_TRUE; - } -} - -/** - * Initializes an MTL texture, using the given width and height as - * a guide. - */ -JNIEXPORT jboolean JNICALL -Java_sun_java2d_metal_MTLSurfaceData_initTexture( - JNIEnv *env, jobject mtlsd, - jlong pData, jboolean isOpaque, - jint width, jint height -) { - if (!MTLSurfaceData_initTexture((BMTLSDOps *)pData, isOpaque, JNI_FALSE, width, height)) - return JNI_FALSE; - MTLSD_SetNativeDimensions(env, (BMTLSDOps *)pData, width, height); - return JNI_TRUE; -} - -/** - * Initializes a framebuffer object, using the given width and height as - * a guide. See MTLSD_InitTextureObject() and MTLSD_initRTexture() - * for more information. - */ -JNIEXPORT jboolean JNICALL -Java_sun_java2d_metal_MTLSurfaceData_initRTexture - (JNIEnv *env, jobject mtlsd, - jlong pData, jboolean isOpaque, - jint width, jint height) -{ - if (!MTLSurfaceData_initTexture((BMTLSDOps *)pData, isOpaque, JNI_TRUE, width, height)) - return JNI_FALSE; - MTLSD_SetNativeDimensions(env, (BMTLSDOps *)pData, width, height); - return JNI_TRUE; -} - -JNIEXPORT jlong JNICALL -Java_sun_java2d_metal_MTLSurfaceData_getMTLTexturePointer(JNIEnv *env, jobject mtlsd, jlong pData) { - if (pData == 0) - return 0; - return ptr_to_jlong(((BMTLSDOps *)pData)->pTexture); -} - -/** - * Initializes nativeWidth/Height fields of the surfaceData object with - * passed arguments. - */ -void -MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *mtlsdo, - jint width, jint height) -{ - jobject sdObject; - - sdObject = (*env)->NewLocalRef(env, mtlsdo->sdOps.sdObject); - if (sdObject == NULL) { - return; - } - - JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width); - if (!((*env)->ExceptionOccurred(env))) { - JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height); - } - - (*env)->DeleteLocalRef(env, sdObject); -} - -/** - * Deletes native Metal resources associated with this surface. - */ -void -MTLSD_Delete(JNIEnv *env, BMTLSDOps *bmtlsdo) -{ - J2dTraceLn3(J2D_TRACE_VERBOSE, "MTLSD_Delete: type=%d %p [tex=%p]", bmtlsdo->drawableType, bmtlsdo, bmtlsdo->pTexture); - if (bmtlsdo->drawableType == MTLSD_WINDOW) { - bmtlsdo->drawableType = MTLSD_UNDEFINED; - } else if ( - bmtlsdo->drawableType == MTLSD_RT_TEXTURE - || bmtlsdo->drawableType == MTLSD_TEXTURE - || bmtlsdo->drawableType == MTLSD_FLIP_BACKBUFFER - ) { - [(NSObject *)bmtlsdo->pTexture release]; - [(NSObject *)bmtlsdo->pStencilTexture release]; - [(NSObject *)bmtlsdo->pStencilData release]; - bmtlsdo->pTexture = NULL; - bmtlsdo->drawableType = MTLSD_UNDEFINED; - } -} - -/** - * This is the implementation of the general DisposeFunc defined in - * SurfaceData.h and used by the Disposer mechanism. It first flushes all - * native Metal resources and then frees any memory allocated within the - * native MTLSDOps structure. - */ -void -MTLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops) -{ - BMTLSDOps *bmtlsdo = (BMTLSDOps *)ops; - jobject graphicsConfig = bmtlsdo->graphicsConfig; - - JNU_CallStaticMethodByName(env, NULL, "sun/java2d/metal/MTLSurfaceData", - "dispose", - "(JLsun/java2d/metal/MTLGraphicsConfig;)V", - ptr_to_jlong(ops), graphicsConfig); - (*env)->DeleteGlobalRef(env, graphicsConfig); - bmtlsdo->graphicsConfig = NULL; -} - -/** - * This is the implementation of the general surface LockFunc defined in - * SurfaceData.h. - */ -jint -MTLSD_Lock(JNIEnv *env, - SurfaceDataOps *ops, - SurfaceDataRasInfo *pRasInfo, - jint lockflags) -{ - JNU_ThrowInternalError(env, "MTLSD_Lock not implemented!"); - return SD_FAILURE; -} - -/** - * This is the implementation of the general GetRasInfoFunc defined in - * SurfaceData.h. - */ -void -MTLSD_GetRasInfo(JNIEnv *env, - SurfaceDataOps *ops, - SurfaceDataRasInfo *pRasInfo) -{ - JNU_ThrowInternalError(env, "MTLSD_GetRasInfo not implemented!"); -} - -/** - * This is the implementation of the general surface UnlockFunc defined in - * SurfaceData.h. - */ -void -MTLSD_Unlock(JNIEnv *env, - SurfaceDataOps *ops, - SurfaceDataRasInfo *pRasInfo) -{ - JNU_ThrowInternalError(env, "MTLSD_Unlock not implemented!"); -} - - -/** - * This function initializes a native window surface and caches the window - * bounds in the given BMTLSDOps. Returns JNI_TRUE if the operation was - * successful; JNI_FALSE otherwise. - */ -jboolean -MTLSD_InitMTLWindow(JNIEnv *env, BMTLSDOps *bmtlsdo) -{ - if (bmtlsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSD_InitMTLWindow: ops are null"); - return JNI_FALSE; - } - - MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps; - if (mtlsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSD_InitMTLWindow: priv ops are null"); - return JNI_FALSE; - } - - AWTView *v = mtlsdo->peerData; - if (v == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSD_InitMTLWindow: view is invalid"); - return JNI_FALSE; - } - - JNI_COCOA_ENTER(env); - NSRect surfaceBounds = [v bounds]; - bmtlsdo->drawableType = MTLSD_WINDOW; - bmtlsdo->isOpaque = JNI_TRUE; - bmtlsdo->width = surfaceBounds.size.width; - bmtlsdo->height = surfaceBounds.size.height; - JNI_COCOA_EXIT(env); - - J2dTraceLn2(J2D_TRACE_VERBOSE, " created window: w=%d h=%d", bmtlsdo->width, bmtlsdo->height); - return JNI_TRUE; -} - -#pragma mark - -#pragma mark "--- MTLSurfaceData methods ---" - -extern LockFunc MTLSD_Lock; -extern GetRasInfoFunc MTLSD_GetRasInfo; -extern UnlockFunc MTLSD_Unlock; - - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLSurfaceData_initOps - (JNIEnv *env, jobject mtlsd, jobject gc, - jlong pConfigInfo, jlong pPeerData, jlong layerPtr, - jint xoff, jint yoff, jboolean isOpaque) -{ - BMTLSDOps *bmtlsdo = (BMTLSDOps *)SurfaceData_InitOps(env, mtlsd, sizeof(BMTLSDOps)); - MTLSDOps *mtlsdo = (MTLSDOps *)malloc(sizeof(MTLSDOps)); - - J2dTraceLn1(J2D_TRACE_INFO, "MTLSurfaceData_initOps p=%p", bmtlsdo); - J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData)); - J2dTraceLn1(J2D_TRACE_INFO, " layerPtr=%p", jlong_to_ptr(layerPtr)); - J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff); - - gc = (*env)->NewGlobalRef(env, gc); - if (gc == NULL) { - JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); - return; - } - - if (mtlsdo == NULL) { - (*env)->DeleteGlobalRef(env, gc); - JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); - return; - } - - // later the graphicsConfig will be used for deallocation of mtlsdo - bmtlsdo->privOps = mtlsdo; - bmtlsdo->graphicsConfig = gc; - - bmtlsdo->sdOps.Lock = MTLSD_Lock; - bmtlsdo->sdOps.GetRasInfo = MTLSD_GetRasInfo; - bmtlsdo->sdOps.Unlock = MTLSD_Unlock; - bmtlsdo->sdOps.Dispose = MTLSD_Dispose; - bmtlsdo->drawableType = MTLSD_UNDEFINED; - - bmtlsdo->isOpaque = isOpaque; - - mtlsdo->peerData = (AWTView *)jlong_to_ptr(pPeerData); - mtlsdo->layer = (MTLLayer *)jlong_to_ptr(layerPtr); - mtlsdo->configInfo = (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); - - if (mtlsdo->configInfo == NULL) { - free(mtlsdo); - JNU_ThrowNullPointerException(env, "Config info is null in initOps"); - } -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLSurfaceData_clearWindow -(JNIEnv *env, jobject mtlsd) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLSurfaceData_clearWindow"); - - BMTLSDOps *bmtlsdo = (MTLSDOps*) SurfaceData_GetOps(env, mtlsd); - MTLSDOps *mtlsdo = (MTLSDOps*) bmtlsdo->privOps; - - mtlsdo->peerData = NULL; - mtlsdo->layer = NULL; -} - -NSString * getSurfaceDescription(const BMTLSDOps * bmtlsdOps) { - if (bmtlsdOps == NULL) - return @"NULL"; - return [NSString stringWithFormat:@"%p [tex=%p, %dx%d, O=%d]", bmtlsdOps, bmtlsdOps->pTexture, bmtlsdOps->width, bmtlsdOps->height, bmtlsdOps->isOpaque]; -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceDataBase.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceDataBase.h deleted file mode 100644 index 261363f42e2..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceDataBase.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLSurfaceDataBase_h_Included -#define MTLSurfaceDataBase_h_Included - -#include "java_awt_image_AffineTransformOp.h" -#include "sun_java2d_pipe_hw_AccelSurface.h" - -#include "SurfaceData.h" -#include "Trace.h" - -/** - * The MTLSDOps structure describes a native Metal surface and contains all - * information pertaining to the native surface. Some information about - * the more important/different fields: - * - * void* privOps; - * Pointer to native-specific (Metal) SurfaceData info, such as the - * native Drawable handle and GraphicsConfig data. - * - * jint drawableType; - * The surface type; can be any one of the surface type constants defined - * below (MTLSD_WINDOW, MTLSD_TEXTURE, etc). - * - * jboolean isOpaque; - * If true, the surface should be treated as being fully opaque. If - * the underlying surface (e.g. MTLTexture/MTLBuffer) has an alpha channel and - * isOpaque is true, then we should take appropriate action to ensure that the - * surface remains fully opaque. - * - * jint width/height; - * The cached surface bounds. For offscreen surface types ( - * MTLSD_TEXTURE, MTLSD_RT_TEXTURE etc.) these values must remain constant. - * Onscreen window surfaces (MTLSD_WINDOW, MTLSD_FLIP_BACKBUFFER, etc.) may - * have their bounds changed in response to a programmatic or user-initiated - * event, so these values represent the last known dimensions. To determine the - * true current bounds of this surface, query the native Drawable through the - * privOps field. - * - * void* pTexture; - * The texture object handle, as generated by MTLTextureDescriptor(). If this - * value is null, the texture has not yet been initialized. - * - * void* pStencilTexture; - * The byte buffer stencil mask used in rendering Metal rendering pass. - */ -typedef struct { - SurfaceDataOps sdOps; - void* privOps; - jobject graphicsConfig; - jint drawableType; - jboolean isOpaque; - jint width; - jint height; - void* pTexture; - void* pStencilData; // stencil data to be rendered to this buffer - void* pStencilTexture; // stencil texture byte buffer stencil mask used in main rendering -} BMTLSDOps; - -#define MTLSD_UNDEFINED sun_java2d_pipe_hw_AccelSurface_UNDEFINED -#define MTLSD_WINDOW sun_java2d_pipe_hw_AccelSurface_WINDOW -#define MTLSD_TEXTURE sun_java2d_pipe_hw_AccelSurface_TEXTURE -#define MTLSD_FLIP_BACKBUFFER sun_java2d_pipe_hw_AccelSurface_FLIP_BACKBUFFER -#define MTLSD_RT_TEXTURE sun_java2d_pipe_hw_AccelSurface_RT_TEXTURE - -/** - * These are shorthand names for the filtering method constants used by - * image transform methods. - */ -#define MTLSD_XFORM_DEFAULT 0 -#define MTLSD_XFORM_NEAREST_NEIGHBOR \ - java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR -#define MTLSD_XFORM_BILINEAR \ - java_awt_image_AffineTransformOp_TYPE_BILINEAR - -/** - * The SurfaceRasterFlags structure contains information about raster (of some MTLTexture): - * - * jboolean isOpaque; - * If true, indicates that this pixel format hasn't alpha component (and values of this component can contain garbage). - * - * jboolean isPremultiplied; - * If true, indicates that this pixel format contains color components that have been pre-multiplied by their - * corresponding alpha component. -*/ -typedef struct { - jboolean isOpaque; - jboolean isPremultiplied; -} SurfaceRasterFlags; - -/** - * Exported methods. - */ -jint MTLSD_Lock(JNIEnv *env, - SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo, - jint lockflags); -void MTLSD_GetRasInfo(JNIEnv *env, - SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo); -void MTLSD_Unlock(JNIEnv *env, - SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo); -void MTLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops); -void MTLSD_Delete(JNIEnv *env, BMTLSDOps *mtlsdo); -jint MTLSD_NextPowerOfTwo(jint val, jint max); - -#endif /* MTLSurfaceDataBase_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.h deleted file mode 100644 index f521be2c170..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLTextRenderer_h_Included -#define MTLTextRenderer_h_Included - -#include <jni.h> -#include <jlong.h> -#include "sun_java2d_pipe_BufferedTextPipe.h" -#include "MTLContext.h" -#include "MTLSurfaceData.h" - -#define BYTES_PER_GLYPH_IMAGE \ - sun_java2d_pipe_BufferedTextPipe_BYTES_PER_GLYPH_IMAGE -#define BYTES_PER_GLYPH_POSITION \ - sun_java2d_pipe_BufferedTextPipe_BYTES_PER_GLYPH_POSITION -#define BYTES_PER_POSITIONED_GLYPH \ - (BYTES_PER_GLYPH_IMAGE + BYTES_PER_GLYPH_POSITION) - -#define OFFSET_CONTRAST sun_java2d_pipe_BufferedTextPipe_OFFSET_CONTRAST -#define OFFSET_RGBORDER sun_java2d_pipe_BufferedTextPipe_OFFSET_RGBORDER -#define OFFSET_SUBPIXPOS sun_java2d_pipe_BufferedTextPipe_OFFSET_SUBPIXPOS -#define OFFSET_POSITIONS sun_java2d_pipe_BufferedTextPipe_OFFSET_POSITIONS - -void MTLTR_EnableGlyphVertexCache(MTLContext *mtlc, BMTLSDOps *dstOps); -void MTLTR_DisableGlyphVertexCache(MTLContext *mtlc); -id<MTLTexture> MTLTR_GetGlyphCacheTexture(); -void MTLTR_FreeGlyphCaches(); - -void MTLTR_DrawGlyphList(JNIEnv *env, MTLContext *mtlc, BMTLSDOps *dstOps, - jint totalGlyphs, jboolean usePositions, - jboolean subPixPos, jboolean rgbOrder, - jint lcdContrast, - jfloat glyphListOrigX, jfloat glyphListOrigY, - unsigned char *images, unsigned char *positions); - -#endif /* MTLTextRenderer_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m deleted file mode 100644 index a52d32a5dea..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m +++ /dev/null @@ -1,845 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <stdlib.h> -#include <limits.h> -#include <math.h> -#include <jlong.h> - -#include "sun_java2d_metal_MTLTextRenderer.h" - -#include "SurfaceData.h" -#include "MTLContext.h" -#include "MTLRenderQueue.h" -#include "MTLTextRenderer.h" -#include "MTLVertexCache.h" -#include "MTLGlyphCache.h" -#include "MTLBlitLoops.h" - -/** - * The following constants define the inner and outer bounds of the - * accelerated glyph cache. - */ -#define MTLTR_CACHE_WIDTH 512 -#define MTLTR_CACHE_HEIGHT 512 -#define MTLTR_CACHE_CELL_WIDTH 32 -#define MTLTR_CACHE_CELL_HEIGHT 32 - -/** - * The current "glyph mode" state. This variable is used to track the - * codepath used to render a particular glyph. This variable is reset to - * MODE_NOT_INITED at the beginning of every call to MTLTR_DrawGlyphList(). - * As each glyph is rendered, the glyphMode variable is updated to reflect - * the current mode, so if the current mode is the same as the mode used - * to render the previous glyph, we can avoid doing costly setup operations - * each time. - */ -typedef enum { - MODE_NOT_INITED, - MODE_USE_CACHE_GRAY, - MODE_USE_CACHE_LCD, - MODE_NO_CACHE_GRAY, - MODE_NO_CACHE_LCD, - MODE_NO_CACHE_COLOR -} GlyphMode; -static GlyphMode glyphMode = MODE_NOT_INITED; - -/** - * There are two separate glyph caches: for AA and for LCD. - * Once one of them is initialized as either GRAY or LCD, it - * stays in that mode for the duration of the application. It should - * be safe to use this one glyph cache for all screens in a multimon - * environment, since the glyph cache texture is shared between all contexts, - * and (in theory) Metal drivers should be smart enough to manage that - * texture across all screens. - */ - -static MTLGlyphCacheInfo *glyphCacheLCD = NULL; -static MTLGlyphCacheInfo *glyphCacheAA = NULL; - -/** - * This value tracks the previous LCD rgbOrder setting, so if the rgbOrder - * value has changed since the last time, it indicates that we need to - * invalidate the cache, which may already store glyph images in the reverse - * order. Note that in most real world applications this value will not - * change over the course of the application, but tests like Font2DTest - * allow for changing the ordering at runtime, so we need to handle that case. - */ -static jboolean lastRGBOrder = JNI_TRUE; - -/** - * This constant defines the size of the tile to use in the - * MTLTR_DrawLCDGlyphNoCache() method. See below for more on why we - * restrict this value to a particular size. - */ -#define MTLTR_NOCACHE_TILE_SIZE 32 - -static struct TxtVertex txtVertices[6]; -static jint vertexCacheIndex = 0; -static id<MTLRenderCommandEncoder> lcdCacheEncoder = nil; - -#define LCD_ADD_VERTEX(TX, TY, DX, DY, DZ) \ - do { \ - struct TxtVertex *v = &txtVertices[vertexCacheIndex++]; \ - v->txtpos[0] = TX; \ - v->txtpos[1] = TY; \ - v->position[0]= DX; \ - v->position[1] = DY; \ - } while (0) - -#define LCD_ADD_TRIANGLES(TX1, TY1, TX2, TY2, DX1, DY1, DX2, DY2) \ - do { \ - LCD_ADD_VERTEX(TX1, TY1, DX1, DY1, 0); \ - LCD_ADD_VERTEX(TX2, TY1, DX2, DY1, 0); \ - LCD_ADD_VERTEX(TX2, TY2, DX2, DY2, 0); \ - LCD_ADD_VERTEX(TX2, TY2, DX2, DY2, 0); \ - LCD_ADD_VERTEX(TX1, TY2, DX1, DY2, 0); \ - LCD_ADD_VERTEX(TX1, TY1, DX1, DY1, 0); \ - } while (0) - -/** - * Initializes the one glyph cache (texture and data structure). - * If lcdCache is JNI_TRUE, the texture will contain RGB data, - * otherwise we will simply store the grayscale/monochrome glyph images - * as intensity values. - */ -static jboolean -MTLTR_InitGlyphCache(MTLContext *mtlc, jboolean lcdCache) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_InitGlyphCache"); - // TODO : Need to verify RGB order in case of LCD - MTLPixelFormat pixelFormat = - lcdCache ? MTLPixelFormatBGRA8Unorm : MTLPixelFormatA8Unorm; - - MTLGlyphCacheInfo *gcinfo; - // init glyph cache data structure - gcinfo = MTLGlyphCache_Init(MTLTR_CACHE_WIDTH, - MTLTR_CACHE_HEIGHT, - MTLTR_CACHE_CELL_WIDTH, - MTLTR_CACHE_CELL_HEIGHT, - MTLVertexCache_FlushGlyphVertexCache); - - if (gcinfo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLTR_InitGlyphCache: could not init MTL glyph cache"); - return JNI_FALSE; - } - - MTLTextureDescriptor *textureDescriptor = - [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat - width:MTLTR_CACHE_WIDTH - height:MTLTR_CACHE_HEIGHT - mipmapped:NO]; - - gcinfo->texture = [mtlc.device newTextureWithDescriptor:textureDescriptor]; - - if (lcdCache) { - glyphCacheLCD = gcinfo; - } else { - glyphCacheAA = gcinfo; - } - - return JNI_TRUE; -} - -id<MTLTexture> -MTLTR_GetGlyphCacheTexture() -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_GetGlyphCacheTexture"); - if (glyphCacheAA != NULL) { - return glyphCacheAA->texture; - } - return NULL; -} - -/** - * Adds the given glyph to the glyph cache (texture and data structure) - * associated with the given MTLContext. - */ -static void -MTLTR_AddToGlyphCache(GlyphInfo *glyph, MTLContext *mtlc, - jboolean lcdCache) -{ - MTLCacheCellInfo *ccinfo; - MTLGlyphCacheInfo *gcinfo; - jint w = glyph->width; - jint h = glyph->height; - - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_AddToGlyphCache"); - if (!lcdCache) { - gcinfo = glyphCacheAA; - } else { - gcinfo = glyphCacheLCD; - } - - if ((gcinfo == NULL) || (glyph->image == NULL)) { - return; - } - - bool isCacheFull = MTLGlyphCache_IsCacheFull(gcinfo, glyph); - if (isCacheFull) { - MTLGlyphCache_Free(gcinfo); - if (!lcdCache) { - MTLTR_InitGlyphCache(mtlc, JNI_FALSE); - gcinfo = glyphCacheAA; - } else { - MTLTR_InitGlyphCache(mtlc, JNI_TRUE); - gcinfo = glyphCacheLCD; - } - } - MTLGlyphCache_AddGlyph(gcinfo, glyph); - ccinfo = (MTLCacheCellInfo *) glyph->cellInfo; - - if (ccinfo != NULL) { - // store glyph image in texture cell - MTLRegion region = { - {ccinfo->x, ccinfo->y, 0}, - {w, h, 1} - }; - if (!lcdCache) { - NSUInteger bytesPerRow = 1 * w; - [gcinfo->texture replaceRegion:region - mipmapLevel:0 - withBytes:glyph->image - bytesPerRow:bytesPerRow]; - } else { - unsigned int imageBytes = w * h * 4; - unsigned char imageData[imageBytes]; - memset(&imageData, 0, sizeof(imageData)); - - int srcIndex = 0; - int dstIndex = 0; - for (int i = 0; i < (w * h); i++) { - imageData[dstIndex++] = glyph->image[srcIndex++]; - imageData[dstIndex++] = glyph->image[srcIndex++]; - imageData[dstIndex++] = glyph->image[srcIndex++]; - imageData[dstIndex++] = 0xFF; - } - - NSUInteger bytesPerRow = 4 * w; - [gcinfo->texture replaceRegion:region - mipmapLevel:0 - withBytes:imageData - bytesPerRow:bytesPerRow]; - } - } -} - -static jboolean -MTLTR_SetLCDContrast(MTLContext *mtlc, - jint contrast, - id<MTLRenderCommandEncoder> encoder) -{ - if (![mtlc.paint isKindOfClass:[MTLColorPaint class]]) { - return JNI_FALSE; - } - MTLColorPaint* cPaint = (MTLColorPaint *) mtlc.paint; - // update the current color settings - double gamma = ((double)contrast) / 100.0; - double invgamma = 1.0/gamma; - jfloat radj, gadj, badj; - jfloat clr[4]; - jint col = cPaint.color; - - J2dTraceLn2(J2D_TRACE_INFO, "primary color %x, contrast %d", col, contrast); - J2dTraceLn2(J2D_TRACE_INFO, "gamma %f, invgamma %f", gamma, invgamma); - - clr[0] = ((col >> 16) & 0xFF)/255.0f; - clr[1] = ((col >> 8) & 0xFF)/255.0f; - clr[2] = ((col) & 0xFF)/255.0f; - - // gamma adjust the primary color - radj = (float)pow(clr[0], gamma); - gadj = (float)pow(clr[1], gamma); - badj = (float)pow(clr[2], gamma); - - struct LCDFrameUniforms uf = { - {radj, gadj, badj}, - {gamma, gamma, gamma}, - {invgamma, invgamma, invgamma}}; - [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; - return JNI_TRUE; -} - -void -MTLTR_EnableGlyphVertexCache(MTLContext *mtlc, BMTLSDOps *dstOps) -{ -J2dTraceLn(J2D_TRACE_INFO, "MTLTR_EnableGlyphVertexCache"); - - if (!MTLVertexCache_InitVertexCache()) { - return; - } - - if (glyphCacheAA == NULL) { - if (!MTLTR_InitGlyphCache(mtlc, JNI_FALSE)) { - return; - } - } - MTLVertexCache_CreateSamplingEncoder(mtlc, dstOps); -} - -void -MTLTR_DisableGlyphVertexCache(MTLContext *mtlc) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DisableGlyphVertexCache"); - MTLVertexCache_FlushGlyphVertexCache(); - MTLVertexCache_FreeVertexCache(); -} - -void MTLTR_FreeGlyphCaches() { - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_FreeGlyphCaches : freeing glyph caches."); - - if (glyphCacheAA != NULL) { - [glyphCacheAA->texture release]; - MTLGlyphCache_Free(glyphCacheAA); - glyphCacheAA = NULL; - } - - if (glyphCacheLCD != NULL) { - [glyphCacheLCD->texture release]; - MTLGlyphCache_Free(glyphCacheLCD); - glyphCacheLCD = NULL; - } -} - -static MTLPaint* storedPaint = nil; - -static void EnableColorGlyphPainting(MTLContext *mtlc) { - storedPaint = mtlc.paint; - mtlc.paint = [[MTLPaint alloc] init]; -} - -static void DisableColorGlyphPainting(MTLContext *mtlc) { - [mtlc.paint release]; - mtlc.paint = storedPaint; - storedPaint = nil; -} - -static jboolean -MTLTR_DrawGrayscaleGlyphViaCache(MTLContext *mtlc, - GlyphInfo *ginfo, jint x, jint y, BMTLSDOps *dstOps) -{ - MTLCacheCellInfo *cell; - jfloat x1, y1, x2, y2; - - if (glyphMode != MODE_USE_CACHE_GRAY) { - if (glyphMode == MODE_NO_CACHE_GRAY) { - MTLVertexCache_DisableMaskCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_LCD) { - [mtlc.encoderManager endEncoder]; - lcdCacheEncoder = nil; - } else if (glyphMode == MODE_NO_CACHE_COLOR) { - DisableColorGlyphPainting(mtlc); - } - MTLTR_EnableGlyphVertexCache(mtlc, dstOps); - glyphMode = MODE_USE_CACHE_GRAY; - } - - if (ginfo->cellInfo == NULL) { - // attempt to add glyph to accelerated glyph cache - MTLTR_AddToGlyphCache(ginfo, mtlc, JNI_FALSE); - - if (ginfo->cellInfo == NULL) { - // we'll just no-op in the rare case that the cell is NULL - return JNI_TRUE; - } - } - - cell = (MTLCacheCellInfo *) (ginfo->cellInfo); - cell->timesRendered++; - - x1 = (jfloat)x; - y1 = (jfloat)y; - x2 = x1 + ginfo->width; - y2 = y1 + ginfo->height; - - MTLVertexCache_AddGlyphQuad(mtlc, - cell->tx1, cell->ty1, - cell->tx2, cell->ty2, - x1, y1, x2, y2); - - return JNI_TRUE; -} - -static jboolean -MTLTR_DrawLCDGlyphViaCache(MTLContext *mtlc, BMTLSDOps *dstOps, - GlyphInfo *ginfo, jint x, jint y, - jboolean rgbOrder, jint contrast) -{ - CacheCellInfo *cell; - jfloat tx1, ty1, tx2, ty2; - jint w = ginfo->width; - jint h = ginfo->height; - - if (glyphMode != MODE_USE_CACHE_LCD) { - if (glyphMode == MODE_NO_CACHE_GRAY) { - MTLVertexCache_DisableMaskCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_GRAY) { - MTLTR_DisableGlyphVertexCache(mtlc); - } else if (glyphMode == MODE_NO_CACHE_COLOR) { - DisableColorGlyphPainting(mtlc); - } - - if (glyphCacheLCD == NULL) { - if (!MTLTR_InitGlyphCache(mtlc, JNI_TRUE)) { - return JNI_FALSE; - } - } - if (lcdCacheEncoder == nil) { - lcdCacheEncoder = [mtlc.encoderManager getLCDEncoder:dstOps->pTexture isSrcOpaque:YES isDstOpaque:YES]; - } - if (rgbOrder != lastRGBOrder) { - // need to invalidate the cache in this case; see comments - // for lastRGBOrder above - MTLGlyphCache_Invalidate(glyphCacheLCD); - lastRGBOrder = rgbOrder; - } - - glyphMode = MODE_USE_CACHE_LCD; - } - - if (ginfo->cellInfo == NULL) { - // attempt to add glyph to accelerated glyph cache - // TODO : Handle RGB order - MTLTR_AddToGlyphCache(ginfo, mtlc, JNI_TRUE); - - if (ginfo->cellInfo == NULL) { - // we'll just no-op in the rare case that the cell is NULL - return JNI_TRUE; - } - } - cell = (CacheCellInfo *) (ginfo->cellInfo); - cell->timesRendered++; - - MTLTR_SetLCDContrast(mtlc, contrast, lcdCacheEncoder); - tx1 = cell->tx1; - ty1 = cell->ty1; - tx2 = cell->tx2; - ty2 = cell->ty2; - - J2dTraceLn4(J2D_TRACE_INFO, "tx1 = %f, ty1 = %f, tx2 = %f, ty2 = %f", tx1, ty1, tx2, ty2); - J2dTraceLn2(J2D_TRACE_INFO, "width = %d height = %d", dstOps->width, dstOps->height); - - LCD_ADD_TRIANGLES(tx1, ty1, tx2, ty2, x, y, x+w, y+h); - - [lcdCacheEncoder setVertexBytes:txtVertices length:sizeof(txtVertices) atIndex:MeshVertexBuffer]; - [lcdCacheEncoder setFragmentTexture:glyphCacheLCD->texture atIndex:0]; - [lcdCacheEncoder setFragmentTexture:dstOps->pTexture atIndex:1]; - - [lcdCacheEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; - - vertexCacheIndex = 0; - - return JNI_TRUE; -} - -static jboolean -MTLTR_DrawGrayscaleGlyphNoCache(MTLContext *mtlc, - GlyphInfo *ginfo, jint x, jint y, BMTLSDOps *dstOps) -{ - jint tw, th; - jint sx, sy, sw, sh; - jint x0; - jint w = ginfo->width; - jint h = ginfo->height; - - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawGrayscaleGlyphNoCache"); - if (glyphMode != MODE_NO_CACHE_GRAY) { - if (glyphMode == MODE_USE_CACHE_GRAY) { - MTLTR_DisableGlyphVertexCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_LCD) { - [mtlc.encoderManager endEncoder]; - lcdCacheEncoder = nil; - } else if (glyphMode == MODE_NO_CACHE_COLOR) { - DisableColorGlyphPainting(mtlc); - } - MTLVertexCache_EnableMaskCache(mtlc, dstOps); - glyphMode = MODE_NO_CACHE_GRAY; - } - - x0 = x; - tw = MTLVC_MASK_CACHE_TILE_WIDTH; - th = MTLVC_MASK_CACHE_TILE_HEIGHT; - - for (sy = 0; sy < h; sy += th, y += th) { - x = x0; - sh = ((sy + th) > h) ? (h - sy) : th; - - for (sx = 0; sx < w; sx += tw, x += tw) { - sw = ((sx + tw) > w) ? (w - sx) : tw; - - J2dTraceLn7(J2D_TRACE_INFO, "sx = %d sy = %d x = %d y = %d sw = %d sh = %d w = %d", sx, sy, x, y, sw, sh, w); - MTLVertexCache_AddMaskQuad(mtlc, - sx, sy, x, y, sw, sh, - w, ginfo->image, - dstOps); - } - } - - return JNI_TRUE; -} - - -static jboolean -MTLTR_DrawLCDGlyphNoCache(MTLContext *mtlc, BMTLSDOps *dstOps, - GlyphInfo *ginfo, jint x, jint y, - jint rowBytesOffset, - jboolean rgbOrder, jint contrast) -{ - jfloat tx1, ty1, tx2, ty2; - jint tw, th; - jint w = ginfo->width; - jint h = ginfo->height; - id<MTLTexture> blitTexture = nil; - - J2dTraceLn2(J2D_TRACE_INFO, "MTLTR_DrawLCDGlyphNoCache x %d, y%d", x, y); - J2dTraceLn3(J2D_TRACE_INFO, "MTLTR_DrawLCDGlyphNoCache rowBytesOffset=%d, rgbOrder=%d, contrast=%d", rowBytesOffset, rgbOrder, contrast); - - - id<MTLRenderCommandEncoder> encoder = nil; - - MTLTextureDescriptor *textureDescriptor = - [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm - width:w - height:h - mipmapped:NO]; - - blitTexture = [mtlc.device newTextureWithDescriptor:textureDescriptor]; - - if (glyphMode != MODE_NO_CACHE_LCD) { - if (glyphMode == MODE_NO_CACHE_GRAY) { - MTLVertexCache_DisableMaskCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_GRAY) { - MTLTR_DisableGlyphVertexCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_LCD) { - [mtlc.encoderManager endEncoder]; - lcdCacheEncoder = nil; - } else if (glyphMode == MODE_NO_CACHE_COLOR) { - DisableColorGlyphPainting(mtlc); - } - - if (blitTexture == nil) { - J2dTraceLn(J2D_TRACE_ERROR, "can't obtain temporary texture object from pool"); - return JNI_FALSE; - } - - - glyphMode = MODE_NO_CACHE_LCD; - } - encoder = [mtlc.encoderManager getLCDEncoder:dstOps->pTexture isSrcOpaque:YES isDstOpaque:YES]; - MTLTR_SetLCDContrast(mtlc, contrast, encoder); - - unsigned int imageBytes = w * h * 4; - unsigned char imageData[imageBytes]; - memset(&imageData, 0, sizeof(imageData)); - - int srcIndex = 0; - int dstIndex = 0; - for (int i = 0; i < (w * h); i++) { - imageData[dstIndex++] = ginfo->image[srcIndex++ + rowBytesOffset]; - imageData[dstIndex++] = ginfo->image[srcIndex++ + rowBytesOffset]; - imageData[dstIndex++] = ginfo->image[srcIndex++ + rowBytesOffset]; - imageData[dstIndex++] = 0xFF; - } - - // copy LCD mask into glyph texture tile - MTLRegion region = MTLRegionMake2D(0, 0, w, h); - - NSUInteger bytesPerRow = 4 * ginfo->width; - [blitTexture replaceRegion:region - mipmapLevel:0 - withBytes:imageData - bytesPerRow:bytesPerRow]; - - tx1 = 0.0f; - ty1 = 0.0f; - tx2 = 1.0f; - ty2 = 1.0f; - - J2dTraceLn2(J2D_TRACE_INFO, "MTLTR_DrawLCDGlyphNoCache : dstOps->width = %d, dstOps->height = %d", dstOps->width, dstOps->height); - - LCD_ADD_TRIANGLES(tx1, ty1, tx2, ty2, x, y, x+w, y+h); - - [encoder setVertexBytes:txtVertices length:sizeof(txtVertices) atIndex:MeshVertexBuffer]; - [encoder setFragmentTexture:blitTexture atIndex:0]; - [encoder setFragmentTexture:dstOps->pTexture atIndex:1]; - - [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; - - vertexCacheIndex = 0; - [mtlc.encoderManager endEncoder]; - [blitTexture release]; - - MTLCommandBufferWrapper* cbwrapper = [mtlc pullCommandBufferWrapper]; - - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - - [commandbuf commit]; - [commandbuf waitUntilCompleted]; - - return JNI_TRUE; -} - -static jboolean -MTLTR_DrawColorGlyphNoCache(MTLContext *mtlc, - GlyphInfo *ginfo, jint x, jint y, BMTLSDOps *dstOps) -{ - id<MTLTexture> dest = dstOps->pTexture; - const void *src = ginfo->image; - jint w = ginfo->width; - jint h = ginfo->height; - jint rowBytes = ginfo->rowBytes; - unsigned int imageSize = rowBytes * h; - - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawColorGlyphNoCache"); - - if (glyphMode != MODE_NO_CACHE_COLOR) { - if (glyphMode == MODE_NO_CACHE_GRAY) { - MTLVertexCache_DisableMaskCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_GRAY) { - MTLTR_DisableGlyphVertexCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_LCD) { - [mtlc.encoderManager endEncoder]; - lcdCacheEncoder = nil; - } - glyphMode = MODE_NO_CACHE_COLOR; - EnableColorGlyphPainting(mtlc); - } - - MTLPooledTextureHandle* texHandle = [mtlc.texturePool getTexture:w height:h format:MTLPixelFormatBGRA8Unorm]; - if (texHandle == nil) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLTR_DrawColorGlyphNoCache: can't obtain temporary texture object from pool"); - return JNI_FALSE; - } - - [[mtlc getCommandBufferWrapper] registerPooledTexture:texHandle]; - - [texHandle.texture replaceRegion:MTLRegionMake2D(0, 0, w, h) - mipmapLevel:0 - withBytes:src - bytesPerRow:rowBytes]; - - drawTex2Tex(mtlc, texHandle.texture, dest, JNI_FALSE, dstOps->isOpaque, INTERPOLATION_NEAREST_NEIGHBOR, - 0, 0, w, h, x, y, x + w, y + h); - - return JNI_TRUE; -} - -// see DrawGlyphList.c for more on this macro... -#define FLOOR_ASSIGN(l, r) \ - if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r)) - -void -MTLTR_DrawGlyphList(JNIEnv *env, MTLContext *mtlc, BMTLSDOps *dstOps, - jint totalGlyphs, jboolean usePositions, - jboolean subPixPos, jboolean rgbOrder, jint lcdContrast, - jfloat glyphListOrigX, jfloat glyphListOrigY, - unsigned char *images, unsigned char *positions) -{ - int glyphCounter; - - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawGlyphList"); - - RETURN_IF_NULL(mtlc); - RETURN_IF_NULL(dstOps); - RETURN_IF_NULL(images); - if (usePositions) { - RETURN_IF_NULL(positions); - } - - glyphMode = MODE_NOT_INITED; - J2dTraceLn1(J2D_TRACE_INFO, "totalGlyphs = %d", totalGlyphs); - jboolean flushBeforeLCD = JNI_FALSE; - - for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { - J2dTraceLn(J2D_TRACE_INFO, "Entered for loop for glyph list"); - jint x, y; - jfloat glyphx, glyphy; - jboolean ok; - GlyphInfo *ginfo = (GlyphInfo *)jlong_to_ptr(NEXT_LONG(images)); - - if (ginfo == NULL) { - // this shouldn't happen, but if it does we'll just break out... - J2dRlsTraceLn(J2D_TRACE_ERROR, - "MTLTR_DrawGlyphList: glyph info is null"); - break; - } - - if (usePositions) { - jfloat posx = NEXT_FLOAT(positions); - jfloat posy = NEXT_FLOAT(positions); - glyphx = glyphListOrigX + posx + ginfo->topLeftX; - glyphy = glyphListOrigY + posy + ginfo->topLeftY; - FLOOR_ASSIGN(x, glyphx); - FLOOR_ASSIGN(y, glyphy); - } else { - glyphx = glyphListOrigX + ginfo->topLeftX; - glyphy = glyphListOrigY + ginfo->topLeftY; - FLOOR_ASSIGN(x, glyphx); - FLOOR_ASSIGN(y, glyphy); - glyphListOrigX += ginfo->advanceX; - glyphListOrigY += ginfo->advanceY; - } - - if (ginfo->image == NULL) { - J2dTraceLn(J2D_TRACE_INFO, "Glyph image is null"); - continue; - } - - J2dTraceLn2(J2D_TRACE_INFO, "Glyph width = %d height = %d", ginfo->width, ginfo->height); - J2dTraceLn1(J2D_TRACE_INFO, "rowBytes = %d", ginfo->rowBytes); - if (ginfo->rowBytes == ginfo->width) { - // grayscale or monochrome glyph data - if (ginfo->width <= MTLTR_CACHE_CELL_WIDTH && - ginfo->height <= MTLTR_CACHE_CELL_HEIGHT) - { - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawGlyphList Grayscale cache"); - ok = MTLTR_DrawGrayscaleGlyphViaCache(mtlc, ginfo, x, y, dstOps); - } else { - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawGlyphList Grayscale no cache"); - ok = MTLTR_DrawGrayscaleGlyphNoCache(mtlc, ginfo, x, y, dstOps); - } - } else if (ginfo->rowBytes == ginfo->width * 4) { - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawGlyphList color glyph no cache"); - ok = MTLTR_DrawColorGlyphNoCache(mtlc, ginfo, x, y, dstOps); - flushBeforeLCD = JNI_FALSE; - } else { - if (!flushBeforeLCD) { - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper* cbwrapper = [mtlc pullCommandBufferWrapper]; - - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - - [commandbuf commit]; - flushBeforeLCD = JNI_TRUE; - } - - // LCD-optimized glyph data - jint rowBytesOffset = 0; - - if (subPixPos) { - jint frac = (jint)((glyphx - x) * 3); - if (frac != 0) { - rowBytesOffset = 3 - frac; - x += 1; - } - } - - if (rowBytesOffset == 0 && - ginfo->width <= MTLTR_CACHE_CELL_WIDTH && - ginfo->height <= MTLTR_CACHE_CELL_HEIGHT) - { - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawGlyphList LCD cache"); - ok = MTLTR_DrawLCDGlyphViaCache(mtlc, dstOps, - ginfo, x, y, - rgbOrder, lcdContrast); - } else { - J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DrawGlyphList LCD no cache"); - ok = MTLTR_DrawLCDGlyphNoCache(mtlc, dstOps, - ginfo, x, y, - rowBytesOffset, - rgbOrder, lcdContrast); - } - } - - if (!ok) { - break; - } - } - /* - * Only in case of grayscale text drawing we need to flush - * cache. Still in case of LCD we are not using any intermediate - * cache. - */ - if (glyphMode == MODE_NO_CACHE_GRAY) { - MTLVertexCache_DisableMaskCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_GRAY) { - MTLTR_DisableGlyphVertexCache(mtlc); - } else if (glyphMode == MODE_USE_CACHE_LCD) { - [mtlc.encoderManager endEncoder]; - lcdCacheEncoder = nil; - } else if (glyphMode == MODE_NO_CACHE_COLOR) { - DisableColorGlyphPainting(mtlc); - } -} - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MTLTextRenderer_drawGlyphList - (JNIEnv *env, jobject self, - jint numGlyphs, jboolean usePositions, - jboolean subPixPos, jboolean rgbOrder, jint lcdContrast, - jfloat glyphListOrigX, jfloat glyphListOrigY, - jlongArray imgArray, jfloatArray posArray) -{ - unsigned char *images; - - J2dTraceLn(J2D_TRACE_INFO, "MTLTextRenderer_drawGlyphList"); - - images = (unsigned char *) - (*env)->GetPrimitiveArrayCritical(env, imgArray, NULL); - if (images != NULL) { - MTLContext *mtlc = MTLRenderQueue_GetCurrentContext(); - BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); - - if (usePositions) { - unsigned char *positions = (unsigned char *) - (*env)->GetPrimitiveArrayCritical(env, posArray, NULL); - if (positions != NULL) { - MTLTR_DrawGlyphList(env, mtlc, dstOps, - numGlyphs, usePositions, - subPixPos, rgbOrder, lcdContrast, - glyphListOrigX, glyphListOrigY, - images, positions); - (*env)->ReleasePrimitiveArrayCritical(env, posArray, - positions, JNI_ABORT); - } - } else { - MTLTR_DrawGlyphList(env, mtlc, dstOps, - numGlyphs, usePositions, - subPixPos, rgbOrder, lcdContrast, - glyphListOrigX, glyphListOrigY, - images, NULL); - } - if (mtlc != NULL) { - RESET_PREVIOUS_OP(); - [mtlc.encoderManager endEncoder]; - MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper]; - id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer]; - [commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) { - [cbwrapper release]; - }]; - [commandbuf commit]; - } - - (*env)->ReleasePrimitiveArrayCritical(env, imgArray, - images, JNI_ABORT); - } -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexturePool.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexturePool.h deleted file mode 100644 index a14cf618e64..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexturePool.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLTexturePool_h_Included -#define MTLTexturePool_h_Included -#include <time.h> -#import "MTLUtils.h" - -@class MTLPoolCell; - -@interface MTLTexturePoolItem : NSObject -@property (readwrite, retain) id<MTLTexture> texture; -@property (readwrite) bool isBusy; -@property (readwrite) time_t lastUsed; -@property (readwrite) bool isMultiSample; -@property (readwrite, assign) MTLTexturePoolItem* prev; -@property (readwrite, retain) MTLTexturePoolItem* next; -@property (readwrite, assign) MTLPoolCell* cell; - -- (id) initWithTexture:(id<MTLTexture>)tex cell:(MTLPoolCell*)cell; -@end - -@interface MTLPooledTextureHandle : NSObject -@property (readonly, assign) id<MTLTexture> texture; -@property (readonly) MTLRegion rect; -- (void) releaseTexture; -@end - -// NOTE: owns all MTLTexture objects -@interface MTLTexturePool : NSObject -@property (readwrite, retain) id<MTLDevice> device; - -- (id) initWithDevice:(id<MTLDevice>)device; -- (MTLPooledTextureHandle *) getTexture:(int)width height:(int)height format:(MTLPixelFormat)format; -- (MTLPooledTextureHandle *) getTexture:(int)width height:(int)height format:(MTLPixelFormat)format - isMultiSample:(bool)isMultiSample; -@end - -@interface MTLPoolCell : NSObject -@property (readwrite, retain) MTLTexturePoolItem* available; -@property (readwrite, assign) MTLTexturePoolItem* availableTail; -@property (readwrite, retain) MTLTexturePoolItem* occupied; -- (MTLTexturePoolItem *)createItem:(id<MTLDevice>)dev - width:(int)width - height:(int)height - format:(MTLPixelFormat)format - isMultiSample:(bool)isMultiSample; -- (NSUInteger)cleanIfBefore:(time_t)lastUsedTimeToRemove; -- (void)releaseItem:(MTLTexturePoolItem *)item; -@end - -#endif /* MTLTexturePool_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m deleted file mode 100644 index 87c489fd11d..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#import "MTLTexturePool.h" -#import "Trace.h" - -#define SCREEN_MEMORY_SIZE_5K (5120*4096*4) //~84 mb -#define MAX_POOL_ITEM_LIFETIME_SEC 30 - -#define CELL_WIDTH_BITS 5 // ~ 32 pixel -#define CELL_HEIGHT_BITS 5 // ~ 32 pixel - -@implementation MTLTexturePoolItem - -@synthesize texture, isBusy, lastUsed, isMultiSample, next, cell; - -- (id) initWithTexture:(id<MTLTexture>)tex cell:(MTLPoolCell*)c{ - self = [super init]; - if (self == nil) return self; - self.texture = tex; - isBusy = NO; - self.next = nil; - self.prev = nil; - self.cell = c; - return self; -} - -- (void) dealloc { - [texture release]; - [super dealloc]; -} - -@end - -@implementation MTLPooledTextureHandle -{ - MTLRegion _rect; - id<MTLTexture> _texture; - MTLTexturePoolItem * _poolItem; -} -@synthesize texture = _texture, rect = _rect; - -- (id) initWithPoolItem:(id<MTLTexture>)texture rect:(MTLRegion)rectangle poolItem:(MTLTexturePoolItem *)poolItem { - self = [super init]; - if (self == nil) return self; - - _rect = rectangle; - _texture = texture; - _poolItem = poolItem; - return self; -} - -- (void) releaseTexture { - [_poolItem.cell releaseItem:_poolItem]; -} - -@end - -@implementation MTLPoolCell { - NSLock* _lock; -} -@synthesize available, availableTail, occupied; - -- (instancetype)init { - self = [super init]; - if (self) { - self.available = nil; - self.availableTail = nil; - self.occupied = nil; - _lock = [[NSLock alloc] init]; - } - return self; -} - -- (void)occupyItem:(MTLTexturePoolItem *)item { - if (item.isBusy) return; - [item retain]; - if (item.prev == nil) { - self.available = item.next; - if (item.next) { - item.next.prev = nil; - } else { - self.availableTail = item.prev; - } - } else { - item.prev.next = item.next; - if (item.next) { - item.next.prev = item.prev; - } else { - self.availableTail = item.prev; - } - item.prev = nil; - } - if (occupied) occupied.prev = item; - item.next = occupied; - self.occupied = item; - [item release]; - item.isBusy = YES; -} - -- (void)releaseItem:(MTLTexturePoolItem *)item { - [_lock lock]; - @try { - if (!item.isBusy) return; - [item retain]; - if (item.prev == nil) { - self.occupied = item.next; - if (item.next) item.next.prev = nil; - } else { - item.prev.next = item.next; - if (item.next) item.next.prev = item.prev; - item.prev = nil; - } - if (self.available) { - self.available.prev = item; - } else { - self.availableTail = item; - } - item.next = self.available; - self.available = item; - item.isBusy = NO; - [item release]; - } @finally { - [_lock unlock]; - } -} - -- (void)addOccupiedItem:(MTLTexturePoolItem *)item { - if (self.occupied) self.occupied.prev = item; - item.next = self.occupied; - item.isBusy = YES; - self.occupied = item; -} - -- (void)removeAvailableItem:(MTLTexturePoolItem*)item { - [item retain]; - if (item.prev == nil) { - self.available = item.next; - if (item.next) { - item.next.prev = nil; - item.next = nil; - } else { - self.availableTail = item.prev; - } - } else { - item.prev.next = item.next; - if (item.next) { - item.next.prev = item.prev; - item.next = nil; - } else { - self.availableTail = item.prev; - } - } - [item release]; -} - -- (void)removeAllItems { - MTLTexturePoolItem *cur = self.available; - while (cur != nil) { - cur = cur.next; - self.available = cur; - } - cur = self.occupied; - while (cur != nil) { - cur = cur.next; - self.occupied = cur; - } - self.availableTail = nil; -} - -- (MTLTexturePoolItem *)createItem:(id<MTLDevice>)dev - width:(int)width - height:(int)height - format:(MTLPixelFormat)format - isMultiSample:(bool)isMultiSample -{ - MTLTextureDescriptor *textureDescriptor = - [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format - width:(NSUInteger) width - height:(NSUInteger) height - mipmapped:NO]; - textureDescriptor.usage = MTLTextureUsageRenderTarget | - MTLTextureUsageShaderRead; - if (isMultiSample) { - textureDescriptor.textureType = MTLTextureType2DMultisample; - textureDescriptor.sampleCount = MTLAASampleCount; - textureDescriptor.storageMode = MTLStorageModePrivate; - } - - id <MTLTexture> tex = (id <MTLTexture>) [[dev newTextureWithDescriptor:textureDescriptor] autorelease]; - MTLTexturePoolItem* item = [[[MTLTexturePoolItem alloc] initWithTexture:tex cell:self] autorelease]; - item.isMultiSample = isMultiSample; - [_lock lock]; - @try { - [self addOccupiedItem:item]; - } @finally { - [_lock unlock]; - } - return item; -} - - -- (NSUInteger)cleanIfBefore:(time_t)lastUsedTimeToRemove { - NSUInteger deallocMem = 0; - [_lock lock]; - MTLTexturePoolItem *cur = availableTail; - @try { - while (cur != nil) { - MTLTexturePoolItem *prev = cur.prev; - if (lastUsedTimeToRemove <= 0 || - cur.lastUsed < lastUsedTimeToRemove) { -#ifdef DEBUG - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, - "MTLTexturePool: remove pool item: tex=%p, w=%d h=%d, elapsed=%d", - cur.texture, cur.texture.width, cur.texture.height, - time(NULL) - cur.lastUsed); -#endif //DEBUG - deallocMem += cur.texture.width * cur.texture.height * 4; - [self removeAvailableItem:cur]; - } else { - if (lastUsedTimeToRemove > 0) break; - } - cur = prev; - } - } @finally { - [_lock unlock]; - } - return deallocMem; -} - -- (MTLTexturePoolItem *)occupyItem:(int)width height:(int)height format:(MTLPixelFormat)format - isMultiSample:(bool)isMultiSample { - int minDeltaArea = -1; - const int requestedPixels = width*height; - MTLTexturePoolItem *minDeltaTpi = nil; - [_lock lock]; - @try { - for (MTLTexturePoolItem *cur = available; cur != nil; cur = cur.next) { - if (cur.texture.pixelFormat != format - || cur.isMultiSample != isMultiSample) { // TODO: use swizzle when formats are not equal - continue; - } - if (cur.texture.width < width || cur.texture.height < height) { - continue; - } - const int deltaArea = (const int) (cur.texture.width * cur.texture.height - requestedPixels); - if (minDeltaArea < 0 || deltaArea < minDeltaArea) { - minDeltaArea = deltaArea; - minDeltaTpi = cur; - if (deltaArea == 0) { - // found exact match in current cell - break; - } - } - } - - if (minDeltaTpi) { - [self occupyItem:minDeltaTpi]; - } - } @finally { - [_lock unlock]; - } - return minDeltaTpi; -} - -- (void) dealloc { - [_lock lock]; - @try { - [self removeAllItems]; - } @finally { - [_lock unlock]; - } - [_lock release]; - [super dealloc]; -} - -@end - -@implementation MTLTexturePool { - int _memoryTotalAllocated; - - void ** _cells; - int _poolCellWidth; - int _poolCellHeight; - uint64_t _maxPoolMemory; -} - -@synthesize device; - -- (id) initWithDevice:(id<MTLDevice>)dev { - self = [super init]; - if (self == nil) return self; - - _memoryTotalAllocated = 0; - _poolCellWidth = 10; - _poolCellHeight = 10; - const int cellsCount = _poolCellWidth * _poolCellHeight; - _cells = (void **)malloc(cellsCount * sizeof(void*)); - memset(_cells, 0, cellsCount * sizeof(void*)); - self.device = dev; - - // recommendedMaxWorkingSetSize typically greatly exceeds SCREEN_MEMORY_SIZE_5K constant. - // It usually corresponds to the VRAM available to the graphics card - _maxPoolMemory = self.device.recommendedMaxWorkingSetSize/2; - - // Set maximum to handle at least 5K screen size - if (_maxPoolMemory < SCREEN_MEMORY_SIZE_5K) { - _maxPoolMemory = SCREEN_MEMORY_SIZE_5K; - } - - return self; -} - -- (void) dealloc { - for (int c = 0; c < _poolCellWidth * _poolCellHeight; ++c) { - MTLPoolCell * cell = _cells[c]; - if (cell != NULL) { - [cell release]; - } - } - free(_cells); - [super dealloc]; -} - -// NOTE: called from RQ-thread (on blit operations) -- (MTLPooledTextureHandle *) getTexture:(int)width height:(int)height format:(MTLPixelFormat)format { - return [self getTexture:width height:height format:format isMultiSample:NO]; -} - -// NOTE: called from RQ-thread (on blit operations) -- (MTLPooledTextureHandle *) getTexture:(int)width height:(int)height format:(MTLPixelFormat)format - isMultiSample:(bool)isMultiSample { - // 1. clean pool if necessary - const int requestedPixels = width*height; - const int requestedBytes = requestedPixels*4; - if (_memoryTotalAllocated + requestedBytes > _maxPoolMemory) { - [self cleanIfNecessary:0]; // release all free textures - } else if (_memoryTotalAllocated + requestedBytes > _maxPoolMemory/2) { - [self cleanIfNecessary:MAX_POOL_ITEM_LIFETIME_SEC]; // release only old free textures - } - - // 2. find free item - const int cellX0 = width >> CELL_WIDTH_BITS; - const int cellY0 = height >> CELL_HEIGHT_BITS; - const int cellX1 = cellX0 + 1; - const int cellY1 = cellY0 + 1; - if (cellX1 > _poolCellWidth || cellY1 > _poolCellHeight) { - const int newCellWidth = cellX1 <= _poolCellWidth ? _poolCellWidth : cellX1; - const int newCellHeight = cellY1 <= _poolCellHeight ? _poolCellHeight : cellY1; - const int newCellsCount = newCellWidth*newCellHeight; -#ifdef DEBUG - J2dTraceLn2(J2D_TRACE_VERBOSE, "MTLTexturePool: resize: %d -> %d", _poolCellWidth * _poolCellHeight, newCellsCount); -#endif - void ** newcells = malloc(newCellsCount*sizeof(void*)); - const int strideBytes = _poolCellWidth * sizeof(void*); - for (int cy = 0; cy < _poolCellHeight; ++cy) { - void ** dst = newcells + cy*newCellWidth; - void ** src = _cells + cy * _poolCellWidth; - memcpy(dst, src, strideBytes); - if (newCellWidth > _poolCellWidth) - memset(dst + _poolCellWidth, 0, (newCellWidth - _poolCellWidth) * sizeof(void*)); - } - if (newCellHeight > _poolCellHeight) { - void ** dst = newcells + _poolCellHeight * newCellWidth; - memset(dst, 0, (newCellHeight - _poolCellHeight) * newCellWidth * sizeof(void*)); - } - free(_cells); - _cells = newcells; - _poolCellWidth = newCellWidth; - _poolCellHeight = newCellHeight; - } - - MTLTexturePoolItem * minDeltaTpi = nil; - int minDeltaArea = -1; - for (int cy = cellY0; cy < cellY1; ++cy) { - for (int cx = cellX0; cx < cellX1; ++cx) { - MTLPoolCell * cell = _cells[cy * _poolCellWidth + cx]; - if (cell != NULL) { - MTLTexturePoolItem* tpi = [cell occupyItem:width height:height - format:format isMultiSample:isMultiSample]; - if (!tpi) continue; - const int deltaArea = (const int) (tpi.texture.width * tpi.texture.height - requestedPixels); - if (minDeltaArea < 0 || deltaArea < minDeltaArea) { - minDeltaArea = deltaArea; - minDeltaTpi = tpi; - if (deltaArea == 0) { - // found exact match in current cell - break; - } - } - } - } - if (minDeltaTpi != nil) { - break; - } - } - - if (minDeltaTpi == NULL) { - MTLPoolCell* cell = _cells[cellY0 * _poolCellWidth + cellX0]; - if (cell == NULL) { - cell = [[MTLPoolCell alloc] init]; - _cells[cellY0 * _poolCellWidth + cellX0] = cell; - } - minDeltaTpi = [cell createItem:device width:width height:height format:format isMultiSample:isMultiSample]; - _memoryTotalAllocated += requestedBytes; - J2dTraceLn5(J2D_TRACE_VERBOSE, "MTLTexturePool: created pool item: tex=%p, w=%d h=%d, pf=%d | total memory = %d Kb", minDeltaTpi.texture, width, height, format, _memoryTotalAllocated/1024); - } - - minDeltaTpi.isBusy = YES; - minDeltaTpi.lastUsed = time(NULL); - return [[[MTLPooledTextureHandle alloc] initWithPoolItem:minDeltaTpi.texture - rect:MTLRegionMake2D(0, 0, - minDeltaTpi.texture.width, - minDeltaTpi.texture.height) - poolItem:minDeltaTpi] autorelease]; -} - -- (void) cleanIfNecessary:(int)lastUsedTimeThreshold { - time_t lastUsedTimeToRemove = - lastUsedTimeThreshold > 0 ? - time(NULL) - lastUsedTimeThreshold : - lastUsedTimeThreshold; - for (int cy = 0; cy < _poolCellHeight; ++cy) { - for (int cx = 0; cx < _poolCellWidth; ++cx) { - MTLPoolCell * cell = _cells[cy * _poolCellWidth + cx]; - if (cell != NULL) { - _memoryTotalAllocated -= [cell cleanIfBefore:lastUsedTimeToRemove]; - } - } - } -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.h deleted file mode 100644 index 59d0d6687db..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLTransform_h_Included -#define MTLTransform_h_Included - -#import <Metal/Metal.h> - -#include <jni.h> - -@interface MTLTransform : NSObject -- (id)init; -- (BOOL)isEqual:(MTLTransform *)other; -- (void)copyFrom:(MTLTransform *)other; - -- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10 - M01:(jdouble) m01 M11:(jdouble) m11 - M02:(jdouble) m02 M12:(jdouble) m12; -- (void)resetTransform; - -- (void)setVertexMatrix:(id<MTLRenderCommandEncoder>)encoder - destWidth:(NSUInteger)dw - destHeight:(NSUInteger)dh; -@end - -#endif // MTLTransform_h_Included diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.m deleted file mode 100644 index 2015cbf5439..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTransform.m +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "MTLTransform.h" - -#include <jni.h> -#include <simd/simd.h> - -#include "common.h" - -@implementation MTLTransform { - jboolean _useTransform; - simd_float4x4 _transform4x4; - simd_float4x4 _normalize4x4; // just a buffer for setVertexMatrix -} - -- (id)init { - self = [super init]; - if (self) { - memset(&_normalize4x4, 0, sizeof(_normalize4x4)); - _normalize4x4.columns[3][0] = -1.f; - _normalize4x4.columns[3][1] = 1.f; - _normalize4x4.columns[3][3] = 1.0; - - _useTransform = JNI_FALSE; - } - return self; -} - -- (BOOL)isEqual:(MTLTransform *)other { - if (self == other) - return YES; - return _useTransform == other->_useTransform - && simd_equal(_transform4x4, other->_transform4x4); -} - -- (void)copyFrom:(MTLTransform *)other { - _useTransform = other->_useTransform; - if (_useTransform) { - _transform4x4 = other->_transform4x4; - } -} - -- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10 - M01:(jdouble) m01 M11:(jdouble) m11 - M02:(jdouble) m02 M12:(jdouble) m12 { - memset(&(_transform4x4), 0, sizeof(_transform4x4)); - _transform4x4.columns[0][0] = m00; - _transform4x4.columns[0][1] = m10; - _transform4x4.columns[1][0] = m01; - _transform4x4.columns[1][1] = m11; - _transform4x4.columns[3][0] = m02; - _transform4x4.columns[3][1] = m12; - _transform4x4.columns[3][3] = 1.0; - _useTransform = JNI_TRUE; -} - -- (void)resetTransform { - _useTransform = JNI_FALSE; -} - -- (void)setVertexMatrix:(id<MTLRenderCommandEncoder>)encoder - destWidth:(NSUInteger)dw - destHeight:(NSUInteger)dh { - // update matrix for vertex shader - _normalize4x4.columns[0][0] = 2/(double)dw; - _normalize4x4.columns[1][1] = -2/(double)dh; - - if (_useTransform) { - simd_float4x4 vertexMatrix = simd_mul(_normalize4x4, _transform4x4); - [encoder setVertexBytes:&(vertexMatrix) length:sizeof(vertexMatrix) atIndex:MatrixBuffer]; - } else { - [encoder setVertexBytes:&(_normalize4x4) length:sizeof(_normalize4x4) atIndex:MatrixBuffer]; - } -} - -@end diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.h deleted file mode 100644 index ff417f43854..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLUtils_h_Included -#define MTLUtils_h_Included - -#import <Metal/Metal.h> - -#define MTLAASampleCount 4 - -#endif /* MTLUtils_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.m deleted file mode 100644 index fe147d5d2ea..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.m +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include "MTLUtils.h" - -#include <jni.h> -#include <simd/simd.h> -#import <ThreadUtilities.h> -#import <PropertiesUtilities.h> -#include "common.h" -#include "Trace.h" - -extern void J2dTraceImpl(int level, jboolean cr, const char *string, ...); -void J2dTraceTraceVector(simd_float4 pt) { - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, "[%lf %lf %lf %lf]", pt.x, pt.y, pt.z, pt.w); -} - -void checkTransform(float * position, simd_float4x4 transform4x4) { - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, "check transform: "); - - simd_float4 fpt = simd_make_float4(position[0], position[1], position[2], 1.f); - simd_float4 fpt_trans = simd_mul(transform4x4, fpt); - J2dTraceTraceVector(fpt); - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, " ===>>> "); - J2dTraceTraceVector(fpt_trans); - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, " "); -} - -static void traceMatrix(simd_float4x4 * mtx) { - for (int row = 0; row < 4; ++row) { - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, " [%lf %lf %lf %lf]", - mtx->columns[0][row], mtx->columns[1][row], mtx->columns[2][row], mtx->columns[3][row]); - } -} - -void traceRaster(char * p, int width, int height, int stride) { - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - unsigned char pix0 = p[y*stride + x*4]; - unsigned char pix1 = p[y*stride + x*4 + 1]; - unsigned char pix2 = p[y*stride + x*4 + 2]; - unsigned char pix3 = p[y*stride + x*4 + 3]; - J2dTraceImpl(J2D_TRACE_INFO, JNI_FALSE,"[%u,%u,%u,%u], ", pix0, pix1, pix2, pix3); - } - J2dTraceImpl(J2D_TRACE_INFO, JNI_TRUE, ""); - } -} - -void tracePoints(jint nPoints, jint *xPoints, jint *yPoints) { - for (int i = 0; i < nPoints; i++) - J2dTraceImpl(J2D_TRACE_INFO, JNI_TRUE, "\t(%d, %d)", *(xPoints++), *(yPoints++)); -} - - -jboolean isOptionEnabled(const char * option) { - JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - - NSString * optionProp = [PropertiesUtilities - javaSystemPropertyForKey:[NSString stringWithUTF8String:option] withEnv:env]; - NSString * lowerCaseProp = [optionProp localizedLowercaseString]; - return [@"true" isEqual:lowerCaseProp]; -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.h deleted file mode 100644 index 240798b7b8a..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 MTLVertexCache_h_Included -#define MTLVertexCache_h_Included -#include "j2d_md.h" -#include "MTLContext.h" -#include "fontscalerdefs.h" - -/** - * Constants that control the size of the vertex cache. - */ -#define MTLVC_MAX_INDEX 250 - -/** - * Constants that control the size of the texture tile cache used for - * mask operations. - */ -#define MTLVC_MASK_CACHE_TILE_WIDTH 32 -#define MTLVC_MASK_CACHE_TILE_HEIGHT 32 -#define MTLVC_MASK_CACHE_TILE_SIZE \ - (MTLVC_MASK_CACHE_TILE_WIDTH * MTLVC_MASK_CACHE_TILE_HEIGHT) - -#define MTLVC_MASK_CACHE_WIDTH_IN_TILES 8 -#define MTLVC_MASK_CACHE_HEIGHT_IN_TILES 4 - -#define MTLVC_MASK_CACHE_WIDTH_IN_TEXELS \ - (MTLVC_MASK_CACHE_TILE_WIDTH * MTLVC_MASK_CACHE_WIDTH_IN_TILES) -#define MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS \ - (MTLVC_MASK_CACHE_TILE_HEIGHT * MTLVC_MASK_CACHE_HEIGHT_IN_TILES) - -/* - * We reserve one (fully opaque) tile in the upper-right corner for - * operations where the mask is null. - */ -#define MTLVC_MASK_CACHE_MAX_INDEX \ - ((MTLVC_MASK_CACHE_WIDTH_IN_TILES * MTLVC_MASK_CACHE_HEIGHT_IN_TILES) - 1) -#define MTLVC_MASK_CACHE_SPECIAL_TILE_X \ - (MTLVC_MASK_CACHE_WIDTH_IN_TEXELS - MTLVC_MASK_CACHE_TILE_WIDTH) -#define MTLVC_MASK_CACHE_SPECIAL_TILE_Y \ - (MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS - MTLVC_MASK_CACHE_TILE_HEIGHT) - -/** - * Exported methods. - */ -jboolean MTLVertexCache_InitVertexCache(); -void MTLVertexCache_FlushVertexCache(MTLContext *mtlc); -void MTLVertexCache_FlushGlyphVertexCache(); -void MTLVertexCache_FreeVertexCache(); - -void MTLVertexCache_EnableMaskCache(MTLContext *mtlc, BMTLSDOps *dstOps); -void MTLVertexCache_DisableMaskCache(MTLContext *mtlc); -void MTLVertexCache_AddMaskQuad(MTLContext *mtlc, - jint srcx, jint srcy, - jint dstx, jint dsty, - jint width, jint height, - jint maskscan, void *mask, - BMTLSDOps *dstOps); -void -MTLVertexCache_AddGlyphQuad(MTLContext *mtlc, - jfloat tx1, jfloat ty1, jfloat tx2, jfloat ty2, - jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2); -void MTLVertexCache_CreateSamplingEncoder(MTLContext *mtlc, BMTLSDOps *dstOps); -#endif /* MTLVertexCache_h_Included */ diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m deleted file mode 100644 index fa702ba7712..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <stdlib.h> -#include <string.h> - -#include "sun_java2d_SunGraphics2D.h" - -#include "MTLPaints.h" -#include "MTLVertexCache.h" -#include "MTLTexturePool.h" -#include "MTLTextRenderer.h" -#include "common.h" - -typedef struct _J2DVertex { - float position[2]; - float txtpos[2]; -} J2DVertex; - -static J2DVertex *vertexCache = NULL; -static jint vertexCacheIndex = 0; - -static MTLPooledTextureHandle * maskCacheTex = NULL; -static jint maskCacheIndex = 0; -static id<MTLRenderCommandEncoder> encoder = NULL; - -#define MTLVC_ADD_VERTEX(TX, TY, DX, DY, DZ) \ - do { \ - J2DVertex *v = &vertexCache[vertexCacheIndex++]; \ - v->txtpos[0] = TX; \ - v->txtpos[1] = TY; \ - v->position[0]= DX; \ - v->position[1] = DY; \ - } while (0) - -#define MTLVC_ADD_TRIANGLES(TX1, TY1, TX2, TY2, DX1, DY1, DX2, DY2) \ - do { \ - MTLVC_ADD_VERTEX(TX1, TY1, DX1, DY1, 0); \ - MTLVC_ADD_VERTEX(TX2, TY1, DX2, DY1, 0); \ - MTLVC_ADD_VERTEX(TX2, TY2, DX2, DY2, 0); \ - MTLVC_ADD_VERTEX(TX2, TY2, DX2, DY2, 0); \ - MTLVC_ADD_VERTEX(TX1, TY2, DX1, DY2, 0); \ - MTLVC_ADD_VERTEX(TX1, TY1, DX1, DY1, 0); \ - } while (0) - -// Next define should exactly match to the amount -// of MTLVC_ADD_VERTEX in MTLVC_ADD_TRIANGLES -#define VERTS_FOR_A_QUAD 6 - -jboolean -MTLVertexCache_InitVertexCache() -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitVertexCache"); - - if (vertexCache == NULL) { - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitVertexCache : vertexCache == NULL"); - vertexCache = (J2DVertex *)malloc(MTLVC_MAX_INDEX * sizeof(J2DVertex)); - if (vertexCache == NULL) { - return JNI_FALSE; - } - } - - return JNI_TRUE; -} - -void -MTLVertexCache_FlushVertexCache(MTLContext *mtlc) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_FlushVertexCache"); - - if (vertexCacheIndex > 0) { - [encoder setVertexBytes: vertexCache length:vertexCacheIndex * sizeof(J2DVertex) - atIndex:MeshVertexBuffer]; - - [encoder setFragmentTexture:maskCacheTex.texture atIndex: 0]; - J2dTraceLn1(J2D_TRACE_INFO, - "MTLVertexCache_FlushVertexCache : encode %d characters", (vertexCacheIndex / 6)); - [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:vertexCacheIndex]; - } - vertexCacheIndex = 0; - maskCacheIndex = 0; - - if (maskCacheTex != nil) { - [[mtlc getCommandBufferWrapper] registerPooledTexture:maskCacheTex]; - [maskCacheTex release]; - maskCacheTex = nil; - } -} - -void -MTLVertexCache_FlushGlyphVertexCache() -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_FlushGlyphVertexCache"); - - if (vertexCacheIndex > 0) { - [encoder setVertexBytes: vertexCache length:vertexCacheIndex * sizeof(J2DVertex) - atIndex:MeshVertexBuffer]; - id<MTLTexture> glyphCacheTex = MTLTR_GetGlyphCacheTexture(); - [encoder setFragmentTexture:glyphCacheTex atIndex: 0]; - J2dTraceLn1(J2D_TRACE_INFO, - "MTLVertexCache_FlushGlyphVertexCache : encode %d characters", (vertexCacheIndex / 6)); - [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:vertexCacheIndex]; - } - vertexCacheIndex = 0; -} - -void MTLVertexCache_FreeVertexCache() -{ - free(vertexCache); - vertexCache = NULL; -} - -static jboolean -MTLVertexCache_InitMaskCache(MTLContext *mtlc) { - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitMaskCache"); - if (maskCacheTex == NULL) { - maskCacheTex = [mtlc.texturePool getTexture:MTLVC_MASK_CACHE_WIDTH_IN_TEXELS - height:MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS - format:MTLPixelFormatA8Unorm]; - [maskCacheTex retain]; - if (maskCacheTex == nil) { - J2dTraceLn(J2D_TRACE_ERROR, "MTLVertexCache_InitMaskCache: can't obtain temporary texture object from pool"); - return JNI_FALSE; - } - } - // init special fully opaque tile in the upper-right corner of - // the mask cache texture - - char tile[MTLVC_MASK_CACHE_TILE_SIZE]; - memset(tile, 0xff, MTLVC_MASK_CACHE_TILE_SIZE); - - jint texx = MTLVC_MASK_CACHE_TILE_WIDTH * (MTLVC_MASK_CACHE_WIDTH_IN_TILES - 1); - - jint texy = MTLVC_MASK_CACHE_TILE_HEIGHT * (MTLVC_MASK_CACHE_HEIGHT_IN_TILES - 1); - - NSUInteger bytesPerRow = 1 * MTLVC_MASK_CACHE_TILE_WIDTH; - - MTLRegion region = { - {texx, texy, 0}, - {MTLVC_MASK_CACHE_TILE_WIDTH, MTLVC_MASK_CACHE_TILE_HEIGHT, 1} - }; - - - // do we really need this?? - [maskCacheTex.texture replaceRegion:region - mipmapLevel:0 - withBytes:tile - bytesPerRow:bytesPerRow]; - - return JNI_TRUE; -} - -void -MTLVertexCache_EnableMaskCache(MTLContext *mtlc, BMTLSDOps *dstOps) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_EnableMaskCache"); - - if (!MTLVertexCache_InitVertexCache()) { - return; - } - - if (maskCacheTex == NULL) { - if (!MTLVertexCache_InitMaskCache(mtlc)) { - return; - } - } - MTLVertexCache_CreateSamplingEncoder(mtlc, dstOps); -} - -void -MTLVertexCache_DisableMaskCache(MTLContext *mtlc) -{ - // TODO : Once we enable check_previous_op - // we will start using DisableMaskCache until then - // we are force flushing vertexcache. - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_DisableMaskCache"); - MTLVertexCache_FlushVertexCache(mtlc); - maskCacheIndex = 0; - free(vertexCache); - vertexCache = NULL; -} - -void -MTLVertexCache_CreateSamplingEncoder(MTLContext *mtlc, BMTLSDOps *dstOps) { - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_CreateSamplingEncoder"); - encoder = [mtlc.encoderManager getTextEncoder:dstOps - isSrcOpaque:NO]; -} - -void -MTLVertexCache_AddMaskQuad(MTLContext *mtlc, - jint srcx, jint srcy, - jint dstx, jint dsty, - jint width, jint height, - jint maskscan, void *mask, - BMTLSDOps *dstOps) -{ - jfloat tx1, ty1, tx2, ty2; - jfloat dx1, dy1, dx2, dy2; - - J2dTraceLn1(J2D_TRACE_INFO, "MTLVertexCache_AddMaskQuad: %d", - maskCacheIndex); - - // MTLVC_ADD_TRIANGLES at the end of this function - // will place VERTS_FOR_A_QUAD vertexes to the vertex cache - // check free space and flush if needed. - if ((maskCacheIndex >= MTLVC_MASK_CACHE_MAX_INDEX) || - ((vertexCacheIndex + VERTS_FOR_A_QUAD) >= MTLVC_MAX_INDEX)) - { - J2dTraceLn2(J2D_TRACE_INFO, "maskCacheIndex = %d, vertexCacheIndex = %d", maskCacheIndex, vertexCacheIndex); - MTLVertexCache_FlushVertexCache(mtlc); - MTLVertexCache_EnableMaskCache(mtlc, dstOps); - maskCacheIndex = 0; - } - - if (mask != NULL) { - jint texx = MTLVC_MASK_CACHE_TILE_WIDTH * - (maskCacheIndex % MTLVC_MASK_CACHE_WIDTH_IN_TILES); - jint texy = MTLVC_MASK_CACHE_TILE_HEIGHT * - (maskCacheIndex / MTLVC_MASK_CACHE_WIDTH_IN_TILES); - J2dTraceLn5(J2D_TRACE_INFO, "texx = %d texy = %d width = %d height = %d maskscan = %d", texx, texy, width, - height, maskscan); - NSUInteger bytesPerRow = 1 * width; - NSUInteger slice = bytesPerRow * srcy + srcx; - MTLRegion region = { - {texx, texy, 0}, - {width, height, 1} - }; - - // Whenever we have source stride bigger that destination stride - // we need to pick appropriate source subtexture. In repalceRegion - // we can give destination subtexturing properly but we can't - // subtexture from system memory glyph we have. So in such - // cases we are creating seperate tile and scan the source - // stride into destination using memcpy. In case of OpenGL we - // can update source pointers, in case of D3D we ar doing memcpy. - // We can use MTLBuffer and then copy source subtexture but that - // adds extra blitting logic. - // TODO : Research more and try removing memcpy logic. - if (maskscan <= width) { - int height_offset = bytesPerRow * srcy; - [maskCacheTex.texture replaceRegion:region - mipmapLevel:0 - withBytes:mask + height_offset - bytesPerRow:bytesPerRow]; - } else { - int dst_offset, src_offset; - int size = 1 * width * height; - char tile[size]; - dst_offset = 0; - for (int i = srcy; i < srcy + height; i++) { - J2dTraceLn2(J2D_TRACE_INFO, "srcx = %d srcy = %d", srcx, srcy); - src_offset = maskscan * i + srcx; - J2dTraceLn2(J2D_TRACE_INFO, "src_offset = %d dst_offset = %d", src_offset, dst_offset); - memcpy(tile + dst_offset, mask + src_offset, width); - dst_offset = dst_offset + width; - } - [maskCacheTex.texture replaceRegion:region - mipmapLevel:0 - withBytes:tile - bytesPerRow:bytesPerRow]; - } - - tx1 = ((jfloat) texx) / MTLVC_MASK_CACHE_WIDTH_IN_TEXELS; - ty1 = ((jfloat) texy) / MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS; - } else { - tx1 = ((jfloat)MTLVC_MASK_CACHE_SPECIAL_TILE_X) / - MTLVC_MASK_CACHE_WIDTH_IN_TEXELS; - ty1 = ((jfloat)MTLVC_MASK_CACHE_SPECIAL_TILE_Y) / - MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS; - } - maskCacheIndex++; - - tx2 = tx1 + (((jfloat)width) / MTLVC_MASK_CACHE_WIDTH_IN_TEXELS); - ty2 = ty1 + (((jfloat)height) / MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS); - - dx1 = (jfloat)dstx; - dy1 = (jfloat)dsty; - dx2 = dx1 + width; - dy2 = dy1 + height; - - J2dTraceLn8(J2D_TRACE_INFO, "tx1 = %f ty1 = %f tx2 = %f ty2 = %f dx1 = %f dy1 = %f dx2 = %f dy2 = %f", tx1, ty1, tx2, ty2, dx1, dy1, dx2, dy2); - MTLVC_ADD_TRIANGLES(tx1, ty1, tx2, ty2, - dx1, dy1, dx2, dy2); -} - -void -MTLVertexCache_AddGlyphQuad(MTLContext *mtlc, - jfloat tx1, jfloat ty1, jfloat tx2, jfloat ty2, - jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2) -{ - J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_AddGlyphQuad"); - - // MTLVC_ADD_TRIANGLES adds VERTS_FOR_A_QUAD vertexes into Cache - // so need to check space for VERTS_FOR_A_QUAD elements - if ((vertexCacheIndex + VERTS_FOR_A_QUAD) >= MTLVC_MAX_INDEX) - { - J2dTraceLn2(J2D_TRACE_INFO, "maskCacheIndex = %d, vertexCacheIndex = %d", maskCacheIndex, vertexCacheIndex); - MTLVertexCache_FlushGlyphVertexCache(); - } - - MTLVC_ADD_TRIANGLES(tx1, ty1, tx2, ty2, - dx1, dy1, dx2, dy2); -} diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h deleted file mode 100644 index 46521ca5b09..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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 __RENDEROPTIONS_H -#define __RENDEROPTIONS_H - -#include <jni.h> -#include "MTLSurfaceDataBase.h" - -// Utility struct to transfer rendering paramenters -typedef struct { - jboolean isTexture; - jboolean isAA; - int interpolation; - SurfaceRasterFlags srcFlags; - SurfaceRasterFlags dstFlags; - jboolean isText; - jboolean isLCD; - jboolean isAAShader; -} RenderOptions; - - -#endif //__RENDEROPTIONS_H diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h deleted file mode 100644 index 556bbf5d88e..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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 COMMON_H -#define COMMON_H - -#include <simd/simd.h> - -#define PGRAM_VERTEX_COUNT 6 -#define QUAD_VERTEX_COUNT 4 -#define GRAD_MAX_FRACTIONS 12 - -enum GradCycleMethod { - GradNoCycle = 0, - GradReflect = 1, - GradRepeat = 2 -}; -enum VertexAttributes { - VertexAttributePosition = 0, - VertexAttributeTexPos = 1, - VertexAttributeITexPos = 2 -}; - -enum BufferIndex { - MeshVertexBuffer = 0, - FrameUniformBuffer = 1, - MatrixBuffer = 2 -}; - -struct FrameUniforms { - vector_float4 color; -}; - -struct TransformMatrix { - matrix_float4x4 transformMatrix; -}; - -struct GradFrameUniforms { - vector_float3 params; - vector_float4 color1; - vector_float4 color2; - int isCyclic; - float extraAlpha; -}; - -struct LinGradFrameUniforms { - vector_float3 params; - float fract[GRAD_MAX_FRACTIONS]; - vector_float4 color[GRAD_MAX_FRACTIONS]; - int numFracts; - int isLinear; - int cycleMethod; - float extraAlpha; -}; - -struct RadGradFrameUniforms { - float fract[GRAD_MAX_FRACTIONS]; - vector_float4 color[GRAD_MAX_FRACTIONS]; - int numFracts; - int isLinear; - int cycleMethod; - vector_float3 m0; - vector_float3 m1; - vector_float3 precalc; - float extraAlpha; -}; - -struct Vertex { - float position[2]; -}; - -struct TxtVertex { - float position[2]; - float txtpos[2]; -}; - -struct AAVertex { - float position[2]; - float otxtpos[2]; - float itxtpos[2]; -}; - -// These values are mapped from AffineTransformOp -#define INTERPOLATION_NEAREST_NEIGHBOR 1 -#define INTERPOLATION_BILINEAR 2 -// #define INTERPOLATION_BICUBIC 3 -// NOTE: Metal samplers doesn't supports bicubic interpolation -// see table 2.7 from https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf -// (probably we need to implement separate fragment shader with bicubic interpolation) - -struct TxtFrameUniforms { - vector_float4 color; - int mode; // NOTE: consider to use bit fields - int isSrcOpaque; - int isDstOpaque; - float extraAlpha; -}; - -struct TxtFrameOpRescaleUniforms { - vector_float4 color; - float extraAlpha; - - int isSrcOpaque; - int isNonPremult; - - vector_float4 normScaleFactors; - vector_float4 normOffsets; -}; - -struct TxtFrameOpConvolveUniforms { - float extraAlpha; - int isSrcOpaque; - vector_float4 imgEdge; - int kernelSize; - int isEdgeZeroFill; -}; - -struct TxtFrameOpLookupUniforms { - float extraAlpha; - int isSrcOpaque; - vector_float4 offset; - int isUseSrcAlpha; - int isNonPremult; -}; - -struct AnchorData -{ - vector_float3 xParams; - vector_float3 yParams; -}; - -struct LCDFrameUniforms { - vector_float3 src_adj; - vector_float3 gamma; - vector_float3 invgamma; -}; - -struct SwizzleUniforms { - unsigned char swizzle[4]; - unsigned char hasAlpha; -}; -#endif diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders.metal b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders.metal deleted file mode 100644 index 722506ab2c3..00000000000 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders.metal +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -#include <simd/simd.h> -#include <metal_stdlib> -#include "common.h" - -using namespace metal; - -struct VertexInput { - float2 position [[attribute(VertexAttributePosition)]]; -}; - -struct TxtVertexInput { - float2 position [[attribute(VertexAttributePosition)]]; - float2 texCoords [[attribute(VertexAttributeTexPos)]]; -}; - -struct AAVertexInput { - float2 position [[attribute(VertexAttributePosition)]]; - float2 oTexCoords [[attribute(VertexAttributeTexPos)]]; - float2 iTexCoords [[attribute(VertexAttributeITexPos)]]; -}; - -struct ColShaderInOut { - float4 position [[position]]; - float ptSize [[point_size]]; - half4 color; -}; - -struct AAShaderInOut { - float4 position [[position]]; - float2 outerTexCoords; - float2 innerTexCoords; - half4 color; -}; - -struct StencilShaderInOut { - float4 position [[position]]; - float ptSize [[point_size]]; - char color; -}; - -struct TxtShaderInOut { - float4 position [[position]]; - float2 texCoords; - float2 tpCoords; -}; - -struct LCDShaderInOut { - float4 position [[position]]; - float2 orig_pos; - float2 texCoords; -}; - -struct GradShaderInOut { - float4 position [[position]]; - float2 texCoords; -}; - - -struct ColShaderInOut_XOR { - float4 position [[position]]; - float ptSize [[point_size]]; - float2 orig_pos; - half4 color; -}; - -struct TxtShaderInOut_XOR { - float4 position [[position]]; - float2 orig_pos; - float2 texCoords; - float2 tpCoords; -}; - -inline float fromLinear(float c) -{ - if (isnan(c)) c = 0.0; - if (c > 1.0) - c = 1.0; - else if (c < 0.0) - c = 0.0; - else if (c < 0.0031308) - c = 12.92 * c; - else - c = 1.055 * powr(c, 1.0/2.4) - 0.055; - return c; -} - -inline float3 fromLinear3(float3 c) { - //c.r = fromLinear(c.r); - //c.g = fromLinear(c.g); - //c.b = fromLinear(c.b); - // Use approximated calculations to match software rendering - c.rgb = 1.055 * pow(c.rgb, float3(0.416667)) - 0.055; - return c; -} - -template <typename Uniforms> inline -float4 frag_single_grad(float a, Uniforms uniforms) -{ - int fa = floor(a); - if (uniforms.isCyclic) { - if (fa%2) { - a = 1.0 + fa - a; - } else { - a = a - fa; - } - } else { - a = saturate(a); - } - return mix(uniforms.color1, uniforms.color2, a); -} - -template <typename Uniforms> inline -float4 frag_multi_grad(float a, Uniforms uniforms) -{ - if (uniforms.cycleMethod > GradNoCycle) { - int fa = floor(a); - a = a - fa; - if (uniforms.cycleMethod == GradReflect && fa%2) { - a = 1.0 - a; - } - } else { - a = saturate(a); - } - - int n = 0; - for (;n < GRAD_MAX_FRACTIONS - 1; n++) { - if (a <= uniforms.fract[n + 1]) break; - } - - a = (a - uniforms.fract[n]) / (uniforms.fract[n + 1] - uniforms.fract[n]); - - float4 c = mix(uniforms.color[n], uniforms.color[n + 1], a); - if (uniforms.isLinear) { - c.rgb = fromLinear3(c.rgb); - } - return c; -} - -vertex ColShaderInOut vert_col(VertexInput in [[stage_in]], - constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]], - constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) { - ColShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - out.ptSize = 1.0; - out.color = half4(uniforms.color.r, uniforms.color.g, uniforms.color.b, uniforms.color.a); - return out; -} - -vertex AAShaderInOut vert_col_aa(AAVertexInput in [[stage_in]], - constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]], - constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) { - AAShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - out.color = half4(uniforms.color.r, uniforms.color.g, uniforms.color.b, uniforms.color.a); - out.outerTexCoords = in.oTexCoords; - out.innerTexCoords = in.iTexCoords; - return out; -} - -vertex StencilShaderInOut vert_stencil(VertexInput in [[stage_in]], - constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]], - constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) { - StencilShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix * pos4; - out.ptSize = 1.0; - out.color = 0xFF; - return out; -} - -vertex GradShaderInOut vert_grad(VertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) { - GradShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - return out; -} - -vertex TxtShaderInOut vert_txt(TxtVertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) { - TxtShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - out.texCoords = in.texCoords; - return out; -} - -vertex LCDShaderInOut vert_txt_lcd(TxtVertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) { - LCDShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - out.orig_pos = in.position; - out.texCoords = in.texCoords; - return out; -} - -vertex TxtShaderInOut vert_txt_tp(TxtVertexInput in [[stage_in]], constant AnchorData& anchorData [[buffer(FrameUniformBuffer)]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) -{ - TxtShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix * pos4; - - // Compute texture coordinates here w.r.t. anchor rect of texture paint - out.tpCoords.x = (anchorData.xParams[0] * in.position.x) + - (anchorData.xParams[1] * in.position.y) + - (anchorData.xParams[2] * out.position.w); - out.tpCoords.y = (anchorData.yParams[0] * in.position.x) + - (anchorData.yParams[1] * in.position.y) + - (anchorData.yParams[2] * out.position.w); - out.texCoords = in.texCoords; - - return out; -} - -vertex GradShaderInOut vert_txt_grad(TxtVertexInput in [[stage_in]], - constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) { - GradShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - out.texCoords = in.texCoords; - return out; -} - -fragment half4 frag_col(ColShaderInOut in [[stage_in]]) { - return in.color; -} - -fragment half4 frag_col_aa(AAShaderInOut in [[stage_in]]) { - float2 oleg1 = dfdx(in.outerTexCoords); - float2 oleg2 = dfdy(in.outerTexCoords); - // Calculate the bounds of the distorted pixel parallelogram. - float2 corner = in.outerTexCoords - (oleg1+oleg2)/2.0; - float2 omin = min(corner, corner+oleg1); - omin = min(omin, corner+oleg2); - omin = min(omin, corner+oleg1+oleg2); - float2 omax = max(corner, corner+oleg1); - omax = max(omax, corner+oleg2); - omax = max(omax, corner+oleg1+oleg2); - // Calculate the vectors for the "legs" of the pixel parallelogram - // for the inner parallelogram. - float2 ileg1 = dfdx(in.innerTexCoords); - float2 ileg2 = dfdy(in.innerTexCoords); - // Calculate the bounds of the distorted pixel parallelogram. - corner = in.innerTexCoords - (ileg1+ileg2)/2.0; - float2 imin = min(corner, corner+ileg1); - imin = min(imin, corner+ileg2); - imin = min(imin, corner+ileg1+ileg2); - float2 imax = max(corner, corner+ileg1); - imax = max(imax, corner+ileg2); - imax = max(imax, corner+ileg1+ileg2); - // Clamp the bounds of the parallelograms to the unit square to - // estimate the intersection of the pixel parallelogram with - // the unit square. The ratio of the 2 rectangle areas is a - // reasonable estimate of the proportion of coverage. - float2 o1 = clamp(omin, 0.0, 1.0); - float2 o2 = clamp(omax, 0.0, 1.0); - float oint = (o2.y-o1.y)*(o2.x-o1.x); - float oarea = (omax.y-omin.y)*(omax.x-omin.x); - float2 i1 = clamp(imin, 0.0, 1.0); - float2 i2 = clamp(imax, 0.0, 1.0); - float iint = (i2.y-i1.y)*(i2.x-i1.x); - float iarea = (imax.y-imin.y)*(imax.x-imin.x); - // Proportion of pixel in outer shape minus the proportion - // of pixel in the inner shape == the coverage of the pixel - // in the area between the two. - float coverage = oint/oarea - iint / iarea; - return (in.color * coverage); -} - -fragment unsigned int frag_stencil(StencilShaderInOut in [[stage_in]]) { - return in.color; -} - -// NOTE: -// 1. consider to make shaders without IF-conditions -// 2. we can pass interpolation mode via uniforms and select corresponding sampler in shader -// but it can cause performance problems (something like getTextureSampler(hint) will be invoked -// for every pixel) - -fragment half4 frag_txt( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> renderTexture [[texture(0)]], - constant TxtFrameUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]] -) { - float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords); - float srcA = uniforms.isSrcOpaque ? 1 : pixelColor.a; - if (uniforms.mode) { - float3 c = mix(pixelColor.rgb, uniforms.color.rgb, srcA); - return half4(c.r, c.g, c.b , - (uniforms.isSrcOpaque) ? - uniforms.color.a : pixelColor.a*uniforms.color.a); - } - - return half4(pixelColor.r, - pixelColor.g, - pixelColor.b, srcA)*uniforms.extraAlpha; -} - -fragment half4 frag_text( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> renderTexture [[texture(0)]], - constant TxtFrameUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]] -) { - float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords); - return half4(uniforms.color * pixelColor.a); -} - -fragment half4 frag_txt_tp(TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> renderTexture [[texture(0)]], - texture2d<float, access::sample> paintTexture [[texture(1)]], - constant TxtFrameUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]] -) { - float4 renderColor = renderTexture.sample(textureSampler, vert.texCoords); - float4 paintColor = paintTexture.sample(textureSampler, vert.tpCoords); - const float srcA = uniforms.isSrcOpaque ? 1 : paintColor.a; - return half4(paintColor.r*renderColor.a, - paintColor.g*renderColor.a, - paintColor.b*renderColor.a, - srcA*renderColor.a) * uniforms.extraAlpha; -} - -fragment half4 frag_txt_grad(GradShaderInOut in [[stage_in]], - constant GradFrameUniforms& uniforms [[buffer(0)]], - texture2d<float, access::sample> renderTexture [[texture(0)]]) -{ - constexpr sampler textureSampler (address::repeat, mag_filter::nearest, - min_filter::nearest); - - float4 renderColor = renderTexture.sample(textureSampler, in.texCoords); - - float3 v = float3(in.position.x-0.5, in.position.y-0.5, 1); - float a = (dot(v,uniforms.params)-0.25)*2.0; - return half4(frag_single_grad(a, uniforms)*renderColor.a)*uniforms.extraAlpha; -} - -fragment half4 frag_txt_lin_grad(GradShaderInOut in [[stage_in]], - constant LinGradFrameUniforms& uniforms [[buffer(0)]], - texture2d<float, access::sample> renderTexture [[texture(0)]]) -{ - constexpr sampler textureSampler (address::repeat, mag_filter::nearest, - min_filter::nearest); - - float4 renderColor = renderTexture.sample(textureSampler, in.texCoords); - float3 v = float3(in.position.x, in.position.y, 1); - float a = dot(v,uniforms.params); - return half4(frag_multi_grad(a, uniforms)*renderColor.a)*uniforms.extraAlpha; -} - -fragment half4 frag_txt_rad_grad(GradShaderInOut in [[stage_in]], - constant RadGradFrameUniforms& uniforms [[buffer(0)]], - texture2d<float, access::sample> renderTexture [[texture(0)]]) -{ - constexpr sampler textureSampler (address::repeat, mag_filter::nearest, - min_filter::nearest); - - float4 renderColor = renderTexture.sample(textureSampler, in.texCoords); - - float3 fragCoord = float3(in.position.x-0.5, in.position.y-0.5, 1); - float x = dot(fragCoord, uniforms.m0); - float y = dot(fragCoord, uniforms.m1); - float xfx = x - uniforms.precalc.x; - float a = (uniforms.precalc.x*xfx + sqrt(xfx*xfx + y*y*uniforms.precalc.y))*uniforms.precalc.z; - return half4(frag_multi_grad(a, uniforms)*renderColor.a)*uniforms.extraAlpha; -} - - -fragment half4 aa_frag_txt( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> renderTexture [[texture(0)]], - texture2d<float, access::sample> stencilTexture [[texture(1)]], - constant TxtFrameUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]] -) { - float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords); - if (!is_null_texture(stencilTexture)) { - float4 stencil = stencilTexture.sample(textureSampler, vert.texCoords); - if (stencil.r == 0.0) { - discard_fragment(); - } - } - return half4(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a); -} - -fragment half4 frag_txt_op_rescale( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> srcTex [[texture(0)]], - constant TxtFrameOpRescaleUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]] -) { - float4 srcColor = srcTex.sample(textureSampler, vert.texCoords); - const float srcA = uniforms.isSrcOpaque ? 1 : srcColor.a; - - // TODO: check uniforms.isNonPremult and pre-multiply if necessary - return half4(srcColor.r*uniforms.normScaleFactors.r + uniforms.normOffsets.r, - srcColor.g*uniforms.normScaleFactors.g + uniforms.normOffsets.g, - srcColor.b*uniforms.normScaleFactors.b + uniforms.normOffsets.b, srcA)*uniforms.extraAlpha; - - // NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the - // same here. - // - // GL-shader impl: - //" vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);" - //" %s" // (placeholder for un-premult code: srcColor.rgb /= srcColor.a;) - //" vec4 result = (srcColor * scaleFactors) + offsets;" // rescale source value - //" %s" // (placeholder for re-premult code: result.rgb *= result.a;) - //" gl_FragColor = result * gl_Color;" // modulate with gl_Color in order to apply extra alpha -} - -fragment half4 frag_txt_op_convolve( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> srcTex [[texture(0)]], - constant TxtFrameOpConvolveUniforms& uniforms [[buffer(1)]], - const device float * kernelVals [[buffer(2)]], - sampler textureSampler [[sampler(0)]] -) { - float4 sum = float4(0, 0, 0, 0); - if (vert.texCoords[0] < uniforms.imgEdge[0] - || vert.texCoords[1] < uniforms.imgEdge[1] - || vert.texCoords[0] > uniforms.imgEdge[2] - || vert.texCoords[1] > uniforms.imgEdge[3] - ) { - if (!uniforms.isEdgeZeroFill) { - sum = srcTex.sample(textureSampler, vert.texCoords); - } - } - - for (int i = 0; i < uniforms.kernelSize; i++) { - float3 kern = float3(kernelVals[i*3], kernelVals[i*3 + 1], kernelVals[i*3 + 2]); - float2 pos = float2(vert.texCoords.x + kern.x, vert.texCoords.y + kern.y); - float4 pixCol = srcTex.sample(textureSampler, pos); - sum.r += kern.z * pixCol.r; - sum.g += kern.z * pixCol.g; - sum.b += kern.z * pixCol.b; - sum.a += kern.z * pixCol.a; - } - const float srcA = uniforms.isSrcOpaque ? 1 : sum.a; - return half4(sum.r, sum.g, sum.b, srcA)*uniforms.extraAlpha; - - // NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the - // same here. - // - // GL-shader impl: - //" if (any(lessThan(gl_TexCoord[0].st, imgEdge.xy)) ||" - //" any(greaterThan(gl_TexCoord[0].st, imgEdge.zw)))" - //" {" - //" %s" // (placeholder for edge condition code) - //" } else {" - //" sum = vec4(0.0);" - //" for (i = 0; i < MAX_KERNEL_SIZE; i++) {" - //" sum +=" - //" kernelVals[i].z *" - //" texture%s(baseImage," - //" gl_TexCoord[0].st + kernelVals[i].xy);" - //" }" - //" }" - //"" - //" gl_FragColor = sum * gl_Color;" // modulate with gl_Color in order to apply extra alpha -} - -fragment half4 frag_txt_op_lookup( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> srcTex [[texture(0)]], - texture2d<float, access::sample> lookupTex [[texture(1)]], - constant TxtFrameOpLookupUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]] -) { - float4 srcColor = srcTex.sample(textureSampler, vert.texCoords); - float4 srcIndex = srcColor - uniforms.offset; - const float2 posR = float2(srcIndex.r, 0.125); - const float2 posG = float2(srcIndex.g, 0.375); - const float2 posB = float2(srcIndex.b, 0.625); - - float4 lookupR = lookupTex.sample(textureSampler, posR); - float4 lookupG = lookupTex.sample(textureSampler, posG); - float4 lookupB = lookupTex.sample(textureSampler, posB); - const float srcA = uniforms.isSrcOpaque ? 1 : srcColor.a; - const float a = uniforms.isUseSrcAlpha ? srcA : lookupTex.sample(textureSampler, float2(srcIndex.a, 0.875)).a; - - // TODO: check uniforms.isNonPremult and pre-multiply if necessary - return half4(lookupR.a, lookupG.a, lookupB.a, a)*uniforms.extraAlpha; - - // NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the - // same here. - // - // GL-shader impl: - //" vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);" - //" %s" // (placeholder for un-premult code) - //" vec4 srcIndex = srcColor - offset;" // subtract offset from original index - // - // // use source value as input to lookup table (note that - // // "v" texcoords are hardcoded to hit texel centers of - // // each row/band in texture) - //" vec4 result;" - //" result.r = texture2D(lookupTable, vec2(srcIndex.r, 0.125)).r;" - //" result.g = texture2D(lookupTable, vec2(srcIndex.g, 0.375)).r;" - //" result.b = texture2D(lookupTable, vec2(srcIndex.b, 0.625)).r;" - //" %s" // (placeholder for alpha store code) - //" %s" // (placeholder for re-premult code) - //" gl_FragColor = result * gl_Color;" // modulate with gl_Color in order to apply extra alpha -} - -fragment half4 frag_grad(GradShaderInOut in [[stage_in]], - constant GradFrameUniforms& uniforms [[buffer(0)]]) { - float3 v = float3(in.position.x-0.5, in.position.y-0.5, 1); - float a = (dot(v,uniforms.params)-0.25)*2.0; - return half4(frag_single_grad(a, uniforms)) * uniforms.extraAlpha; -} - -// LinGradFrameUniforms -fragment half4 frag_lin_grad(GradShaderInOut in [[stage_in]], - constant LinGradFrameUniforms& uniforms [[buffer(0)]]) { - float3 v = float3(in.position.x-0.5, in.position.y-0.5, 1); - float a = dot(v, uniforms.params); - return half4(frag_multi_grad(a, uniforms))*uniforms.extraAlpha; -} - -fragment half4 frag_rad_grad(GradShaderInOut in [[stage_in]], - constant RadGradFrameUniforms& uniforms [[buffer(0)]]) { - float3 fragCoord = float3(in.position.x-0.5, in.position.y-0.5, 1); - float x = dot(fragCoord, uniforms.m0); - float y = dot(fragCoord, uniforms.m1); - float xfx = x - uniforms.precalc.x; - float a = (uniforms.precalc.x*xfx + sqrt(xfx*xfx + y*y*uniforms.precalc.y))*uniforms.precalc.z; - return half4(frag_multi_grad(a, uniforms))*uniforms.extraAlpha; -} - -vertex TxtShaderInOut vert_tp(VertexInput in [[stage_in]], - constant AnchorData& anchorData [[buffer(FrameUniformBuffer)]], - constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) -{ - TxtShaderInOut out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix * pos4; - - // Compute texture coordinates here w.r.t. anchor rect of texture paint - out.texCoords.x = (anchorData.xParams[0] * in.position.x) + - (anchorData.xParams[1] * in.position.y) + - (anchorData.xParams[2] * out.position.w); - out.texCoords.y = (anchorData.yParams[0] * in.position.x) + - (anchorData.yParams[1] * in.position.y) + - (anchorData.yParams[2] * out.position.w); - - return out; -} - -fragment half4 frag_tp( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> renderTexture [[texture(0)]], - constant TxtFrameUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]]) -{ - float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords); - const float srcA = uniforms.isSrcOpaque ? 1 : pixelColor.a; - return half4(pixelColor.r, pixelColor.g, pixelColor.b, srcA) * uniforms.extraAlpha; -} - - - -/* The variables involved in the equation can be expressed as follows: - * - * Cs = Color component of the source (foreground color) [0.0, 1.0] - * Cd = Color component of the destination (background color) [0.0, 1.0] - * Cr = Color component to be written to the destination [0.0, 1.0] - * Ag = Glyph alpha (aka intensity or coverage) [0.0, 1.0] - * Ga = Gamma adjustment in the range [1.0, 2.5] - * (^ means raised to the power) - * - * And here is the theoretical equation approximated by this shader: - * - * Cr = (Ag*(Cs^Ga) + (1-Ag)*(Cd^Ga)) ^ (1/Ga) - */ -fragment float4 lcd_color( - LCDShaderInOut vert [[stage_in]], - texture2d<float, access::sample> glyphTexture [[texture(0)]], - texture2d<float, access::sample> dstTexture [[texture(1)]], - constant LCDFrameUniforms& uniforms [[buffer(1)]]) -{ - float3 src_adj = uniforms.src_adj; - float3 gamma = uniforms.gamma; - float3 invgamma = uniforms.invgamma; - - constexpr sampler glyphTextureSampler (address::repeat, - mag_filter::nearest, - min_filter::nearest); - - // load the RGB value from the glyph image at the current texcoord - float3 glyph_clr = float3(glyphTexture.sample(glyphTextureSampler, vert.texCoords)); - - if (glyph_clr.r == 0.0f && glyph_clr.g == 0.0f && glyph_clr.b == 0.0f) { - // zero coverage, so skip this fragment - discard_fragment(); - } - - // load the RGB value from the corresponding destination pixel - uint2 texCoord = {(unsigned int)(vert.orig_pos.x), (unsigned int)(vert.orig_pos.y)}; - float4 dst_clr = dstTexture.read(texCoord); - - // gamma adjust the dest color - float3 dst_adj = pow(dst_clr.rgb, gamma); - - // linearly interpolate the three color values - float3 result = mix(dst_adj, src_adj, glyph_clr); - - // gamma re-adjust the resulting color (alpha is always set to 1.0) - return float4(pow(result.rgb, invgamma), 1.0); - -} -// Compute shader to transfer clipping data to the texture used for manual clipping in -// aa_frag_txt shader -kernel void stencil2tex(const device uchar *imageBuffer [[buffer(0)]], - device uchar4 *outputBuffer [[buffer(1)]], - uint gid [[thread_position_in_grid]]) -{ - uchar p = imageBuffer[gid]; - outputBuffer[gid] = uchar4(p, p, p, p); -} - -// work item deals with 4 byte pixel -// assuming that data is aligned -kernel void swizzle_to_rgba(const device uchar *imageBuffer [[buffer(0)]], - device uchar *outputBuffer [[buffer(1)]], - constant SwizzleUniforms& uniforms [[buffer(2)]], - constant uint& size [[buffer(3)]], - uint gid [[thread_position_in_grid]]) -{ - if (gid > size) { - return; - } - - outputBuffer[4 * gid] = imageBuffer[4 * gid + uniforms.swizzle[0]]; // r - outputBuffer[4 * gid + 1] = imageBuffer[4 * gid + uniforms.swizzle[1]]; // g - outputBuffer[4 * gid + 2] = imageBuffer[4 * gid + uniforms.swizzle[2]]; // b - - if (uniforms.hasAlpha) { - outputBuffer[4 * gid + 3] = imageBuffer[4 * gid + uniforms.swizzle[3]]; - } else { - outputBuffer[4 * gid + 3] = 255; - } -} - -// ---------------------------------------------------------------------------- -// Shaders for rendering in XOR Mode -// ---------------------------------------------------------------------------- -vertex ColShaderInOut_XOR vert_col_xorMode(VertexInput in [[stage_in]], - constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]], - constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) -{ - ColShaderInOut_XOR out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - out.ptSize = 1.0; - out.orig_pos = in.position; - out.color = half4(uniforms.color.r, uniforms.color.g, uniforms.color.b, uniforms.color.a); - return out; -} - -fragment half4 frag_col_xorMode(ColShaderInOut_XOR in [[stage_in]], - texture2d<float, access::read> renderTexture [[texture(0)]]) -{ - uint2 texCoord = {(unsigned int)(in.orig_pos.x), (unsigned int)(in.orig_pos.y)}; - - float4 pixelColor = renderTexture.read(texCoord); - half4 color = in.color; - - half4 c; - c.r = float( (unsigned char)(pixelColor.r * 255.0) ^ (unsigned char)(color.r * 255.0)) / 255.0f; - c.g = float( (unsigned char)(pixelColor.g * 255.0) ^ (unsigned char)(color.g * 255.0)) / 255.0f; - c.b = float( (unsigned char)(pixelColor.b * 255.0) ^ (unsigned char)(color.b * 255.0)) / 255.0f; - c.a = 1.0; - - return c; -} - - -vertex TxtShaderInOut_XOR vert_txt_xorMode( - TxtVertexInput in [[stage_in]], - constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) -{ - TxtShaderInOut_XOR out; - float4 pos4 = float4(in.position, 0.0, 1.0); - out.position = transform.transformMatrix*pos4; - out.orig_pos = in.position; - out.texCoords = in.texCoords; - return out; -} - -fragment half4 frag_txt_xorMode( - TxtShaderInOut_XOR vert [[stage_in]], - texture2d<float, access::sample> renderTexture [[texture(0)]], - texture2d<float, access::read> backgroundTexture [[texture(1)]], - constant TxtFrameUniforms& uniforms [[buffer(1)]], - sampler textureSampler [[sampler(0)]]) -{ - uint2 texCoord = {(unsigned int)(vert.orig_pos.x), (unsigned int)(vert.orig_pos.y)}; - float4 bgColor = backgroundTexture.read(texCoord); - - float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords); - float srcA = uniforms.isSrcOpaque ? 1 : pixelColor.a; - - float4 c; - if (uniforms.mode) { - c = mix(pixelColor, uniforms.color, srcA); - } else { - c = float4(pixelColor.r, - pixelColor.g, - pixelColor.b, srcA)*uniforms.extraAlpha; - } - - half4 ret; - ret.r = half( (unsigned char)(c.r * 255.0) ^ (unsigned char)(bgColor.r * 255.0)) / 255.0f; - ret.g = half( (unsigned char)(c.g * 255.0) ^ (unsigned char)(bgColor.g * 255.0)) / 255.0f; - ret.b = half( (unsigned char)(c.b * 255.0) ^ (unsigned char)(bgColor.b * 255.0)) / 255.0f; - ret.a = c.a + (1.0 - c.a) * bgColor.a; - - return ret; -} - - -/* - // -------------------------------------------------------------------------------------- - Currently, gradient paint and texture paint XOR mode rendering has been implemented - through tile based rendering (similar to OGL) that uses MTLBlitLoops_SurfaceToSwBlit method for - getting framebuffer tiles and render using a different render pipe (not MTLRenderer) - - In metal, we can avoid tile based rendering and use below shaders. - NOTE: These two shaders are incomplete and need some tweak. - // -------------------------------------------------------------------------------------- - -fragment half4 frag_grad_xorMode(GradShaderInOut_XOR in [[stage_in]], - texture2d<float, access::read> renderTexture [[texture(0)]], - constant GradFrameUniforms& uniforms [[buffer(0)]]) { - uint2 texCoord = {(unsigned int)(in.orig_pos.x), (unsigned int)(in.orig_pos.y)}; - float4 pixelColor = renderTexture.read(texCoord); - - float3 v = float3(in.position.x, in.position.y, 1); - float a = (dot(v,uniforms.params)-0.25)*2.0; - float4 c = mix(uniforms.color1, uniforms.color2, a); - - half4 ret; - ret.r = float( (unsigned char)(pixelColor.r * 255.0) ^ (unsigned char)(c.r * 255.0)) / 255.0f; - ret.g = float( (unsigned char)(pixelColor.g * 255.0) ^ (unsigned char)(c.g * 255.0)) / 255.0f; - ret.b = float( (unsigned char)(pixelColor.b * 255.0) ^ (unsigned char)(c.b * 255.0)) / 255.0f; - - return half4(ret); -} - - -fragment half4 frag_tp_xorMode( - TxtShaderInOut vert [[stage_in]], - texture2d<float, access::sample> renderTexture [[texture(0)]], - texture2d<float, access::read> backgroundTexture [[texture(1)]], - constant int& xorColor[[buffer(0)]]) -{ - uint2 texCoord = {(unsigned int)(vert.orig_pos.x), (unsigned int)(vert.orig_pos.y)}; - float4 bgColor = backgroundTexture.read(texCoord); - - constexpr sampler textureSampler (address::repeat, - mag_filter::nearest, - min_filter::nearest); - - float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords); - - pixelColor.r = float( (unsigned char)(pixelColor.r * 255.0) ^ ((xorColor >> 16) & 0xFF) ) / 255.0f; - pixelColor.g = float( (unsigned char)(pixelColor.g * 255.0) ^ ((xorColor >> 8) & 0xFF)) / 255.0f; - pixelColor.b = float( (unsigned char)(pixelColor.b * 255.0) ^ (xorColor & 0xFF)) / 255.0f; - pixelColor.a = 1.0; - - half4 ret; - ret.r = half( (unsigned char)(pixelColor.r * 255.0) ^ (unsigned char)(bgColor.r * 255.0)) / 255.0f; - ret.g = half( (unsigned char)(pixelColor.g * 255.0) ^ (unsigned char)(bgColor.g * 255.0)) / 255.0f; - ret.b = half( (unsigned char)(pixelColor.b * 255.0) ^ (unsigned char)(bgColor.b * 255.0)) / 255.0f; - ret.a = 1.0; - - return ret; - - // This implementation defaults alpha to 1.0 as if source is opaque - //TODO : implement alpha component value if source is transparent -} -*/ -- GitLab