Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
skiko
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuqiang
skiko
Commits
f1b93ac7
Commit
f1b93ac7
authored
Apr 27, 2021
by
Roman Sedaikin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reinit render target/surface/canvas only when the SkiaLayer is resized (DirectX).
parent
0158424b
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
325 additions
and
218 deletions
+325
-218
App.kt
...kijaInjectSample/src/main/kotlin/SkijaInjectSample/App.kt
+25
-5
directXRedrawer.cc
skiko/src/jvmMain/cpp/windows/directXRedrawer.cc
+242
-193
ContextHandler.kt
...Main/kotlin/org/jetbrains/skiko/context/ContextHandler.kt
+1
-1
Direct3DContextHandler.kt
...lin/org/jetbrains/skiko/context/Direct3DContextHandler.kt
+49
-14
Direct3DRedrawer.kt
...n/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt
+8
-5
No files found.
samples/SkijaInjectSample/src/main/kotlin/SkijaInjectSample/App.kt
View file @
f1b93ac7
...
...
@@ -90,11 +90,31 @@ class Renderer(
var
canvas
:
Canvas
?
=
null
override
fun
onRender
(
canvas
:
Canvas
,
width
:
Int
,
height
:
Int
,
nanoTime
:
Long
)
{
this
.
canvas
=
canvas
val
contentScale
=
layer
.
contentScale
canvas
.
scale
(
contentScale
,
contentScale
)
displayScene
(
this
,
(
width
/
contentScale
).
toInt
(),
(
height
/
contentScale
).
toInt
(),
nanoTime
)
layer
.
needRedraw
()
// this.canvas = canvas
// val contentScale = layer.contentScale
// canvas.scale(contentScale, contentScale)
// displayScene(this, (width / contentScale).toInt(), (height / contentScale).toInt(), nanoTime)
// layer.needRedraw()
//////////////////////////////////////////////////
val
pictureRecorder
=
PictureRecorder
()
val
pictureCanvas
=
pictureRecorder
.
beginRecording
(
Rect
.
makeLTRB
(
0f
,
0f
,
100f
,
100f
)
)
pictureCanvas
.
drawLine
(
0f
,
0f
,
100f
,
100f
,
Paint
())
val
picture
=
pictureRecorder
.
finishRecordingAsPicture
()
canvas
.
drawPicture
(
picture
,
null
,
Paint
()
// if we replace it by null, everything will be normal
)
canvas
.
drawLine
(
100f
,
0f
,
0f
,
100f
,
Paint
())
//////////////////////////////////////////////////
}
}
...
...
skiko/src/jvmMain/cpp/windows/directXRedrawer.cc
View file @
f1b93ac7
...
...
@@ -33,32 +33,27 @@ const int BuffersCount = 2;
// with the current Swing/Skia integration.
// If PC has other graphics cards suitable for DirectX12, one of them will be used. Otherwise,
// rendering will falls back to OpenGL.
const
std
::
vector
<
std
::
wstring
>
adapterBlacklist
{
const
std
::
vector
<
std
::
wstring
>
adapterBlacklist
{
L"Microsoft Basic Render Driver"
,
L"Intel(R) HD Graphics 520"
,
L"Intel(R) HD Graphics 530"
,
L"NVIDIA GeForce GTX 750 Ti"
,
L"NVIDIA GeForce GTX 960M"
,
L"NVIDIA Quadro M2000M"
};
L"NVIDIA Quadro M2000M"
};
class
DirectXDevice
{
public
:
HWND
window
;
GrD3DBackendContext
backendContext
;
gr_cp
<
ID3D12Device
>
device
;
gr_cp
<
IDXGISwapChain3
>
swapChain
;
gr_cp
<
ID3D12CommandQueue
>
queue
;
gr_cp
<
ID3D12Resource
>
buffers
[
BuffersCount
];
gr_cp
<
ID3D12Fence
>
fence
;
uint64_t
fenceValues
[
BuffersCount
];
HANDLE
fenceEvent
=
NULL
;
uint64_t
fenceValue
;
unsigned
int
bufferIndex
=
0
;
unsigned
int
bufferWidth
=
0
;
unsigned
int
bufferHeight
=
0
;
bool
isSizeEqualTo
(
unsigned
int
width
,
unsigned
int
height
)
{
return
width
==
bufferWidth
&&
height
==
bufferHeight
;
}
unsigned
int
bufferIndex
;
~
DirectXDevice
()
{
...
...
@@ -66,6 +61,10 @@ public:
{
CloseHandle
(
fenceEvent
);
}
for
(
int
i
=
0
;
i
<
BuffersCount
;
i
++
)
{
buffers
[
i
].
reset
(
nullptr
);
}
fence
.
reset
(
nullptr
);
swapChain
.
reset
(
nullptr
);
queue
.
reset
(
nullptr
);
...
...
@@ -76,20 +75,20 @@ public:
extern
"C"
{
HRESULT
D3D12CreateDevice
(
HRESULT
D3D12CreateDevice
(
IUnknown
*
pAdapter
,
D3D_FEATURE_LEVEL
MinimumFeatureLevel
,
REFIID
riid
,
void
**
ppDevice
)
{
void
**
ppDevice
)
{
typedef
HRESULT
(
*
D3D12CreateDevice_t
)(
IUnknown
*
pAdapter
,
IUnknown
*
pAdapter
,
D3D_FEATURE_LEVEL
MinimumFeatureLevel
,
REFIID
riid
,
void
**
ppDevice
);
void
**
ppDevice
);
static
D3D12CreateDevice_t
impl
=
nullptr
;
if
(
!
impl
)
{
if
(
!
impl
)
{
auto
d3d12dll
=
LoadLibrary
(
TEXT
(
"D3D12.dll"
));
if
(
!
d3d12dll
)
return
E_NOTIMPL
;
...
...
@@ -98,22 +97,22 @@ HRESULT D3D12CreateDevice(
return
E_NOTIMPL
;
}
return
impl
(
pAdapter
,
MinimumFeatureLevel
,
riid
,
ppDevice
);
}
}
HRESULT
D3D12SerializeRootSignature
(
HRESULT
D3D12SerializeRootSignature
(
const
D3D12_ROOT_SIGNATURE_DESC
*
pRootSignature
,
D3D_ROOT_SIGNATURE_VERSION
Version
,
ID3DBlob
**
ppBlob
,
ID3DBlob
**
ppErrorBlob
)
{
ID3DBlob
**
ppErrorBlob
)
{
typedef
HRESULT
(
*
D3D12SerializeRootSignature_t
)(
const
D3D12_ROOT_SIGNATURE_DESC
*
pRootSignature
,
D3D_ROOT_SIGNATURE_VERSION
Version
,
ID3DBlob
**
ppBlob
,
ID3DBlob
**
ppErrorBlob
);
ID3DBlob
**
ppErrorBlob
);
static
D3D12SerializeRootSignature_t
impl
=
nullptr
;
if
(
!
impl
)
{
if
(
!
impl
)
{
auto
d3d12dll
=
LoadLibrary
(
TEXT
(
"D3D12.dll"
));
if
(
!
d3d12dll
)
return
E_NOTIMPL
;
...
...
@@ -122,18 +121,18 @@ HRESULT D3D12SerializeRootSignature(
return
E_NOTIMPL
;
}
return
impl
(
pRootSignature
,
Version
,
ppBlob
,
ppErrorBlob
);
}
}
HRESULT
CreateDXGIFactory1
(
HRESULT
CreateDXGIFactory1
(
REFIID
riid
,
void
**
ppFactory
)
{
void
**
ppFactory
)
{
typedef
HRESULT
(
*
CreateDXGIFactory1_t
)(
REFIID
riid
,
void
**
ppFactory
);
void
**
ppFactory
);
static
CreateDXGIFactory1_t
impl
=
nullptr
;
if
(
!
impl
)
{
if
(
!
impl
)
{
auto
dxgidll
=
LoadLibrary
(
TEXT
(
"Dxgi.dll"
));
if
(
!
dxgidll
)
return
E_NOTIMPL
;
...
...
@@ -142,20 +141,20 @@ HRESULT CreateDXGIFactory1(
return
E_NOTIMPL
;
}
return
impl
(
riid
,
ppFactory
);
}
}
HRESULT
CreateDXGIFactory2
(
HRESULT
CreateDXGIFactory2
(
UINT
Flags
,
REFIID
riid
,
void
**
ppFactory
)
{
void
**
ppFactory
)
{
typedef
HRESULT
(
*
CreateDXGIFactory2_t
)(
UINT
Flags
,
REFIID
riid
,
void
**
ppFactory
);
void
**
ppFactory
);
static
CreateDXGIFactory2_t
impl
=
nullptr
;
if
(
!
impl
)
{
if
(
!
impl
)
{
auto
dxgidll
=
LoadLibrary
(
TEXT
(
"Dxgi.dll"
));
if
(
!
dxgidll
)
return
E_NOTIMPL
;
...
...
@@ -164,9 +163,9 @@ HRESULT CreateDXGIFactory2(
return
E_NOTIMPL
;
}
return
impl
(
Flags
,
riid
,
ppFactory
);
}
}
HRESULT
D3DCompile
(
HRESULT
D3DCompile
(
LPCVOID
pSrcData
,
SIZE_T
SrcDataSize
,
LPCSTR
pSourceName
,
...
...
@@ -177,8 +176,8 @@ HRESULT D3DCompile(
UINT
Flags1
,
UINT
Flags2
,
ID3DBlob
**
ppCode
,
ID3DBlob
**
ppErrorMsgs
)
{
ID3DBlob
**
ppErrorMsgs
)
{
typedef
HRESULT
(
*
D3DCompile_t
)(
LPCVOID
pSrcData
,
SIZE_T
SrcDataSize
,
...
...
@@ -190,10 +189,10 @@ HRESULT D3DCompile(
UINT
Flags1
,
UINT
Flags2
,
ID3DBlob
**
ppCode
,
ID3DBlob
**
ppErrorMsgs
);
ID3DBlob
**
ppErrorMsgs
);
static
D3DCompile_t
impl
=
nullptr
;
if
(
!
impl
)
{
if
(
!
impl
)
{
auto
d3dcompilerdll
=
LoadLibrary
(
TEXT
(
"d3dcompiler_47.dll"
));
if
(
!
d3dcompilerdll
)
return
E_NOTIMPL
;
...
...
@@ -202,48 +201,15 @@ HRESULT D3DCompile(
return
E_NOTIMPL
;
}
return
impl
(
pSrcData
,
SrcDataSize
,
pSourceName
,
pDefines
,
pInclude
,
pEntrypoint
,
pTarget
,
Flags1
,
Flags2
,
ppCode
,
ppErrorMsgs
);
}
JNIEXPORT
jlong
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_makeDirectXContext
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
GrD3DBackendContext
backendContext
=
d3dDevice
->
backendContext
;
return
toJavaPointer
(
GrDirectContext
::
MakeDirect3D
(
backendContext
).
release
());
}
JNIEXPORT
jlong
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_makeDirectXRenderTarget
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
,
jint
width
,
jint
height
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
if
(
!
d3dDevice
->
isSizeEqualTo
(
width
,
height
))
{
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
swapChain
->
ResizeBuffers
(
BuffersCount
,
width
,
height
,
DXGI_FORMAT_R8G8B8A8_UNORM
,
0
));
d3dDevice
->
bufferWidth
=
width
;
d3dDevice
->
bufferHeight
=
height
;
}
d3dDevice
->
bufferIndex
=
d3dDevice
->
swapChain
->
GetCurrentBackBufferIndex
();
ID3D12Resource
*
buffer
;
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
swapChain
->
GetBuffer
(
d3dDevice
->
bufferIndex
,
IID_PPV_ARGS
(
&
buffer
)));
GrD3DTextureResourceInfo
info
(
buffer
,
nullptr
,
D3D12_RESOURCE_STATE_PRESENT
,
DXGI_FORMAT_R8G8B8A8_UNORM
,
1
,
1
,
0
);
GrBackendRenderTarget
*
renderTarget
=
new
GrBackendRenderTarget
(
width
,
height
,
info
);
return
toJavaPointer
(
renderTarget
);
}
bool
isBlacklisted
(
IDXGIAdapter1
*
hardwareAdapter
)
bool
isBlacklisted
(
IDXGIAdapter1
*
hardwareAdapter
)
{
DXGI_ADAPTER_DESC1
desc
;
hardwareAdapter
->
GetDesc1
(
&
desc
);
std
::
wstring
currentAdapterName
(
desc
.
Description
);
for
(
std
::
wstring
name
:
adapterBlacklist
)
{
for
(
std
::
wstring
name
:
adapterBlacklist
)
{
if
(
currentAdapterName
==
name
)
{
fwprintf
(
stderr
,
L"Graphics card: %s is blacklisted.
\n
"
,
name
.
c_str
());
...
...
@@ -312,13 +278,21 @@ HRESULT D3DCompile(
d3dDevice
->
backendContext
.
fAdapter
=
hardwareAdapter
;
d3dDevice
->
backendContext
.
fDevice
=
device
;
d3dDevice
->
backendContext
.
fQueue
=
queue
;
d3dDevice
->
backendContext
.
fProtectedContext
=
GrProtected
::
kNo
;
d3dDevice
->
device
=
device
;
d3dDevice
->
queue
=
queue
;
d3dDevice
->
window
=
(
HWND
)
windowHandle
;
// Make the swapchain
HWND
fWindow
=
(
HWND
)
windowHandle
;
return
toJavaPointer
(
d3dDevice
);
}
JNIEXPORT
void
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_initSwapChain
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
// Make the swapchain
gr_cp
<
IDXGIFactory4
>
swapChainFactory
;
GR_D3D_CALL_ERRCHECK
(
CreateDXGIFactory2
(
0
,
IID_PPV_ARGS
(
&
swapChainFactory
)));
...
...
@@ -326,71 +300,145 @@ HRESULT D3DCompile(
swapChainDesc
.
BufferCount
=
BuffersCount
;
swapChainDesc
.
Format
=
DXGI_FORMAT_R8G8B8A8_UNORM
;
swapChainDesc
.
BufferUsage
=
DXGI_USAGE_RENDER_TARGET_OUTPUT
;
swapChainDesc
.
SwapEffect
=
DXGI_SWAP_EFFECT_FLIP_
SEQUENTIAL
;
swapChainDesc
.
SwapEffect
=
DXGI_SWAP_EFFECT_FLIP_
DISCARD
;
swapChainDesc
.
SampleDesc
.
Count
=
1
;
swapChainDesc
.
SampleDesc
.
Quality
=
0
;
swapChainDesc
.
Scaling
=
DXGI_SCALING_NONE
;
DXGI_SWAP_CHAIN_FULLSCREEN_DESC
swapChainFSDesc
=
{};
swapChainFSDesc
.
Windowed
=
TRUE
;
gr_cp
<
IDXGISwapChain1
>
swapChain
;
GR_D3D_CALL_ERRCHECK
(
swapChainFactory
->
CreateSwapChainForHwnd
(
d3dDevice
->
queue
.
get
(),
fWindow
,
&
swapChainDesc
,
&
swapChainFSDesc
,
nullptr
,
&
swapChain
));
GR_D3D_CALL_ERRCHECK
(
swapChainFactory
->
CreateSwapChainForHwnd
(
d3dDevice
->
queue
.
get
(),
d3dDevice
->
window
,
&
swapChainDesc
,
nullptr
,
nullptr
,
&
swapChain
));
GR_D3D_CALL_ERRCHECK
(
swapChainFactory
->
MakeWindowAssociation
(
d3dDevice
->
window
,
DXGI_MWA_NO_ALT_ENTER
));
GR_D3D_CALL_ERRCHECK
(
swapChain
->
QueryInterface
(
IID_PPV_ARGS
(
&
d3dDevice
->
swapChain
)));
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
device
->
CreateFence
(
0
,
D3D12_FENCE_FLAG_NONE
,
IID_PPV_ARGS
(
&
d3dDevice
->
fence
)));
d3dDevice
->
fenceEvent
=
CreateEvent
(
nullptr
,
FALSE
,
FALSE
,
nullptr
);
RECT
windowRect
;
GetWindowRect
(
d3dDevice
->
window
,
&
windowRect
);
unsigned
int
w
=
windowRect
.
right
-
windowRect
.
left
;
unsigned
int
h
=
windowRect
.
bottom
-
windowRect
.
top
;
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
swapChain
->
ResizeBuffers
(
BuffersCount
,
w
,
h
,
DXGI_FORMAT_R8G8B8A8_UNORM
,
0
));
swapChainFactory
.
reset
(
nullptr
);
swapChainFactory
.
reset
(
nullptr
);
}
return
toJavaPointer
(
d3dDevice
);
JNIEXPORT
void
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_initFence
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
for
(
int
i
=
0
;
i
<
BuffersCount
;
i
++
)
{
d3dDevice
->
fenceValues
[
i
]
=
10000
;
}
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
device
->
CreateFence
(
d3dDevice
->
fenceValues
[
0
],
D3D12_FENCE_FLAG_NONE
,
IID_PPV_ARGS
(
&
d3dDevice
->
fence
)));
d3dDevice
->
fenceEvent
=
CreateEvent
(
nullptr
,
FALSE
,
FALSE
,
nullptr
);
SkASSERT
(
d3dDevice
->
fenceEvent
);
}
JNIEXPORT
jlong
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_makeDirectXContext
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
GrD3DBackendContext
backendContext
=
d3dDevice
->
backendContext
;
return
toJavaPointer
(
GrDirectContext
::
MakeDirect3D
(
backendContext
).
release
());
}
JNIEXPORT
jlong
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_makeDirectXSurface
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
,
jlong
contextPtr
,
jint
width
,
jint
height
,
jint
index
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
GrDirectContext
*
context
=
fromJavaPointer
<
GrDirectContext
*>
(
contextPtr
);
GrD3DTextureResourceInfo
info
(
nullptr
,
nullptr
,
D3D12_RESOURCE_STATE_PRESENT
,
DXGI_FORMAT_R8G8B8A8_UNORM
,
1
,
1
,
0
);
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
swapChain
->
GetBuffer
(
index
,
IID_PPV_ARGS
(
&
d3dDevice
->
buffers
[
index
])));
info
.
fResource
=
d3dDevice
->
buffers
[
index
];
SkSurfaceProps
surfaceProps
(
0
,
kRGB_H_SkPixelGeometry
);
GrBackendTexture
backendTexture
((
int
)
d3dDevice
->
buffers
[
index
]
->
GetDesc
().
Width
,
(
int
)
d3dDevice
->
buffers
[
index
]
->
GetDesc
().
Height
,
info
);
return
toJavaPointer
(
SkSurface
::
MakeFromBackendTexture
(
context
,
backendTexture
,
kTopLeft_GrSurfaceOrigin
,
0
,
kRGBA_8888_SkColorType
,
SkColorSpace
::
MakeSRGB
(),
&
surfaceProps
)
.
release
());
}
JNIEXPORT
void
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_resizeBuffers
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
,
jint
width
,
jint
height
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
if
(
!
d3dDevice
->
isSizeEqualTo
(
width
,
height
)
)
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
for
(
int
i
=
0
;
i
<
BuffersCount
;
i
++
)
{
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
swapChain
->
ResizeBuffers
(
BuffersCount
,
width
,
height
,
DXGI_FORMAT_R8G8B8A8_UNORM
,
0
));
d3dDevice
->
bufferWidth
=
width
;
d3dDevice
->
bufferHeight
=
height
;
if
(
d3dDevice
->
fence
->
GetCompletedValue
()
<
d3dDevice
->
fenceValues
[
i
])
{
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
fence
->
SetEventOnCompletion
(
d3dDevice
->
fenceValues
[
i
],
d3dDevice
->
fenceEvent
));
WaitForSingleObjectEx
(
d3dDevice
->
fenceEvent
,
INFINITE
,
FALSE
);
}
d3dDevice
->
buffers
[
i
].
reset
(
nullptr
);
}
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
swapChain
->
ResizeBuffers
(
BuffersCount
,
width
,
height
,
DXGI_FORMAT_R8G8B8A8_UNORM
,
0
));
}
JNIEXPORT
void
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_finishFrame
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
,
jlong
contextPtr
,
jlong
surfacePtr
,
jboolean
isVsyncEnabled
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
SkSurface
*
surface
=
fromJavaPointer
<
SkSurface
*>
(
surfacePtr
);
GrDirectContext
*
fContext
=
fromJavaPointer
<
GrDirectContext
*>
(
contextPtr
);
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
SkSurface
*
surface
=
fromJavaPointer
<
SkSurface
*>
(
surfacePtr
);
GrDirectContext
*
context
=
fromJavaPointer
<
GrDirectContext
*>
(
contextPtr
);
surface
->
flushAndSubmit
();
surface
->
flushAndSubmit
(
true
);
surface
->
flush
(
SkSurface
::
BackendSurfaceAccess
::
kPresent
,
GrFlushInfo
());
fC
ontext
->
flush
({});
fC
ontext
->
submit
(
true
);
c
ontext
->
flush
({});
c
ontext
->
submit
(
true
);
// 1 value in [Present(1, 0)] enables vblank wait so this is how vertical sync works in DirectX.
const
UINT64
fenceValue
=
d3dDevice
->
fenceValues
[
d3dDevice
->
bufferIndex
];
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
swapChain
->
Present
((
int
)
isVsyncEnabled
,
0
));
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
queue
->
Signal
(
d3dDevice
->
fence
.
get
(),
fenceValue
));
}
const
UINT64
fence
=
d3dDevice
->
fenceValue
;
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
queue
->
Signal
(
d3dDevice
->
fence
.
get
(),
fence
));
d3dDevice
->
fenceValue
++
;
if
(
d3dDevice
->
fence
->
GetCompletedValue
()
<
fence
)
JNIEXPORT
void
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_disposeDevice
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
,
jlong
contextPtr
)
{
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
fence
->
SetEventOnCompletion
(
fence
,
d3dDevice
->
fenceEvent
));
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
GrDirectContext
*
context
=
fromJavaPointer
<
GrDirectContext
*>
(
contextPtr
);
context
->
flush
({});
context
->
submit
(
true
);
for
(
int
i
=
0
;
i
<
BuffersCount
;
i
++
)
{
if
(
d3dDevice
->
fence
->
GetCompletedValue
()
<
d3dDevice
->
fenceValues
[
i
])
{
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
fence
->
SetEventOnCompletion
(
d3dDevice
->
fenceValues
[
i
],
d3dDevice
->
fenceEvent
));
WaitForSingleObjectEx
(
d3dDevice
->
fenceEvent
,
INFINITE
,
FALSE
);
}
}
JNIEXPORT
void
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_disposeDevice
(
delete
d3dDevice
;
}
JNIEXPORT
jint
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_getBufferIndex
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
delete
d3dDevice
;
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
const
UINT64
fenceValue
=
d3dDevice
->
fenceValues
[
d3dDevice
->
bufferIndex
];
d3dDevice
->
bufferIndex
=
d3dDevice
->
swapChain
->
GetCurrentBackBufferIndex
();
if
(
d3dDevice
->
fence
->
GetCompletedValue
()
<
fenceValue
)
{
GR_D3D_CALL_ERRCHECK
(
d3dDevice
->
fence
->
SetEventOnCompletion
(
fenceValue
,
d3dDevice
->
fenceEvent
));
WaitForSingleObjectEx
(
d3dDevice
->
fenceEvent
,
INFINITE
,
FALSE
);
}
d3dDevice
->
fenceValues
[
d3dDevice
->
bufferIndex
]
=
fenceValue
+
1
;
return
d3dDevice
->
bufferIndex
;
}
JNIEXPORT
jstring
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_getAdapterName
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
JNIEXPORT
jstring
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_getAdapterName
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
DXGI_ADAPTER_DESC1
desc
;
d3dDevice
->
backendContext
.
fAdapter
->
GetDesc1
(
&
desc
);
...
...
@@ -400,8 +448,9 @@ HRESULT D3DCompile(
return
result
;
}
JNIEXPORT
jlong
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_getAdapterMemorySize
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
JNIEXPORT
jlong
JNICALL
Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_getAdapterMemorySize
(
JNIEnv
*
env
,
jobject
redrawer
,
jlong
devicePtr
)
{
DirectXDevice
*
d3dDevice
=
fromJavaPointer
<
DirectXDevice
*>
(
devicePtr
);
DXGI_ADAPTER_DESC1
desc
;
d3dDevice
->
backendContext
.
fAdapter
->
GetDesc1
(
&
desc
);
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/ContextHandler.kt
View file @
f1b93ac7
...
...
@@ -47,7 +47,7 @@ internal abstract class ContextHandler(val layer: SkiaLayer) {
destroyContext
()
}
fun
disposeCanvas
()
{
open
fun
disposeCanvas
()
{
surface
?.
close
()
renderTarget
?.
close
()
}
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt
View file @
f1b93ac7
...
...
@@ -10,6 +10,9 @@ import org.jetbrains.skiko.redrawer.Direct3DRedrawer
import
java.lang.ref.Reference
internal
class
Direct3DContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
private
val
bufferCount
=
2
private
var
surfaces
:
Array
<
Surface
?>
=
arrayOfNulls
(
bufferCount
)
val
directXRedrawer
:
Direct3DRedrawer
get
()
=
layer
.
redrawer
!!
as
Direct3DRedrawer
...
...
@@ -22,7 +25,6 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer)
throw
Exception
(
"Failed to create DirectX12 device."
)
}
context
=
directXRedrawer
.
makeContext
(
device
)
val
printDeviceEnabled
=
System
.
getProperty
(
"skiko.hardwareInfo.enabled"
)
==
"true"
if
(
System
.
getProperty
(
"skiko.hardwareInfo.enabled"
)
==
"true"
)
{
println
(
hardwareInfo
())
}
...
...
@@ -34,28 +36,51 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer)
return
true
}
override
fun
initCanvas
()
{
disposeCanvas
()
private
var
currentWidth
=
0
private
var
currentHeight
=
0
private
fun
isSizeChanged
(
width
:
Int
,
height
:
Int
):
Boolean
{
if
(
width
!=
currentWidth
||
height
!=
currentHeight
)
{
currentWidth
=
width
currentHeight
=
height
return
true
}
return
false
}
private
var
isD3DInited
=
false
override
fun
initCanvas
()
{
val
scale
=
layer
.
contentScale
val
w
=
(
layer
.
width
*
scale
).
toInt
().
coerceAtLeast
(
0
)
val
h
=
(
layer
.
height
*
scale
).
toInt
().
coerceAtLeast
(
0
)
renderTarget
=
directXRedrawer
.
makeRenderTarget
(
device
,
w
,
h
)
if
(
isSizeChanged
(
w
,
h
))
{
disposeCanvas
()
context
?.
flush
()
surface
=
Surface
.
makeFromBackendRenderTarget
(
context
!!
,
renderTarget
!!
,
SurfaceOrigin
.
TOP_LEFT
,
SurfaceColorFormat
.
RGBA_8888
,
ColorSpace
.
getSRGB
()
)
if
(!
isD3DInited
)
{
directXRedrawer
.
initSwapChain
(
device
)
}
else
{
directXRedrawer
.
resizeBuffers
(
device
,
w
,
h
)
}
try
{
for
(
bufferIndex
in
0
..
bufferCount
-
1
)
{
surfaces
[
bufferIndex
]
=
directXRedrawer
.
makeSurface
(
device
,
Native
.
getPtr
(
context
!!
),
w
,
h
,
bufferIndex
)
}
}
finally
{
Reference
.
reachabilityFence
(
context
!!
)
}
if
(!
isD3DInited
)
{
isD3DInited
=
true
directXRedrawer
.
initFence
(
device
)
}
}
surface
=
surfaces
[
directXRedrawer
.
getBufferIndex
(
device
)]
canvas
=
surface
!!
.
canvas
}
override
fun
flush
()
{
super
.
flush
()
try
{
directXRedrawer
.
finishFrame
(
device
,
...
...
@@ -69,8 +94,18 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer)
}
override
fun
destroyContext
()
{
try
{
directXRedrawer
.
disposeDevice
(
device
,
Native
.
getPtr
(
context
!!
))
}
finally
{
Reference
.
reachabilityFence
(
context
!!
)
}
context
?.
close
()
directXRedrawer
.
disposeDevice
(
device
)
}
override
fun
disposeCanvas
()
{
for
(
bufferIndex
in
0
..
bufferCount
-
1
)
{
surfaces
[
bufferIndex
]
?.
close
()
}
}
override
fun
hardwareInfo
():
String
{
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt
View file @
f1b93ac7
...
...
@@ -3,7 +3,7 @@ package org.jetbrains.skiko.redrawer
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.swing.Swing
import
kotlinx.coroutines.withContext
import
org.jetbrains.skija.
BackendRenderTarget
import
org.jetbrains.skija.
Surface
import
org.jetbrains.skija.DirectContext
import
org.jetbrains.skiko.FrameDispatcher
import
org.jetbrains.skiko.SkiaLayer
...
...
@@ -60,8 +60,8 @@ internal class Direct3DRedrawer(
makeDirectXContext
(
device
)
)
fun
make
RenderTarget
(
device
:
Long
,
width
:
Int
,
height
:
Int
)
=
BackendRenderTarget
(
makeDirectX
RenderTarget
(
device
,
width
,
height
)
fun
make
Surface
(
device
:
Long
,
context
:
Long
,
width
:
Int
,
height
:
Int
,
index
:
Int
)
=
Surface
(
makeDirectX
Surface
(
device
,
context
,
width
,
height
,
index
)
)
fun
createDevice
():
Long
=
createDirectXDevice
(
layer
.
windowHandle
)
...
...
@@ -72,10 +72,13 @@ internal class Direct3DRedrawer(
external
fun
createDirectXDevice
(
windowHandle
:
Long
):
Long
external
fun
makeDirectXContext
(
device
:
Long
):
Long
external
fun
makeDirectX
RenderTarget
(
device
:
Long
,
width
:
Int
,
height
:
Int
):
Long
external
fun
makeDirectX
Surface
(
device
:
Long
,
context
:
Long
,
width
:
Int
,
height
:
Int
,
index
:
Int
):
Long
external
fun
resizeBuffers
(
device
:
Long
,
width
:
Int
,
height
:
Int
)
private
external
fun
finishFrame
(
device
:
Long
,
context
:
Long
,
surface
:
Long
,
isVsyncEnabled
:
Boolean
)
external
fun
disposeDevice
(
device
:
Long
)
external
fun
disposeDevice
(
device
:
Long
,
context
:
Long
)
external
fun
getBufferIndex
(
device
:
Long
):
Int
external
fun
initSwapChain
(
device
:
Long
)
external
fun
initFence
(
device
:
Long
)
external
fun
getAdapterName
(
device
:
Long
):
String
external
fun
getAdapterMemorySize
(
device
:
Long
):
Long
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment