Unverified Commit ea760f80 authored by Pavel's avatar Pavel Committed by GitHub

Add configurable logger, solidify workaround for JBR-5274 (#683)

* sometimes when we change scale via `EasyRes` or when we close/open lid and window is migrated to other screen `paint` is not called

see FL-18544

* customizable logger behaviour

* add debug logs in AWT layer
parent db11bf1d
...@@ -81,6 +81,7 @@ actual open class SkiaLayer internal constructor( ...@@ -81,6 +81,7 @@ actual open class SkiaLayer internal constructor(
layout = null layout = null
backedLayer = object : HardwareLayer(externalAccessibleFactory) { backedLayer = object : HardwareLayer(externalAccessibleFactory) {
override fun paint(g: java.awt.Graphics) { override fun paint(g: java.awt.Graphics) {
Logger.debug { "Paint called on $this" }
checkContentScale() checkContentScale()
// 1. JPanel.paint is not always called (in rare cases). // 1. JPanel.paint is not always called (in rare cases).
...@@ -123,6 +124,7 @@ actual open class SkiaLayer internal constructor( ...@@ -123,6 +124,7 @@ actual open class SkiaLayer internal constructor(
} }
addPropertyChangeListener("graphicsContextScaleTransform") { addPropertyChangeListener("graphicsContextScaleTransform") {
Logger.debug { "graphicsContextScaleTransform changed for $this" }
redrawer?.syncSize() redrawer?.syncSize()
notifyChange(PropertyKind.ContentScale) notifyChange(PropertyKind.ContentScale)
...@@ -140,6 +142,7 @@ actual open class SkiaLayer internal constructor( ...@@ -140,6 +142,7 @@ actual open class SkiaLayer internal constructor(
private var fullscreenAdapter = FullscreenAdapter(backedLayer) private var fullscreenAdapter = FullscreenAdapter(backedLayer)
override fun removeNotify() { override fun removeNotify() {
Logger.debug { "SkiaLayer.awt#removeNotify $this" }
val window = SwingUtilities.getRoot(this) as Window val window = SwingUtilities.getRoot(this) as Window
window.removeComponentListener(fullscreenAdapter) window.removeComponentListener(fullscreenAdapter)
dispose() dispose()
...@@ -147,6 +150,7 @@ actual open class SkiaLayer internal constructor( ...@@ -147,6 +150,7 @@ actual open class SkiaLayer internal constructor(
} }
override fun addNotify() { override fun addNotify() {
Logger.debug { "SkiaLayer.awt#addNotify $this" }
super.addNotify() super.addNotify()
val window = SwingUtilities.getRoot(this) as Window val window = SwingUtilities.getRoot(this) as Window
window.addComponentListener(fullscreenAdapter) window.addComponentListener(fullscreenAdapter)
...@@ -314,7 +318,7 @@ actual open class SkiaLayer internal constructor( ...@@ -314,7 +318,7 @@ actual open class SkiaLayer internal constructor(
redrawer = renderFactory.createRedrawer(this, renderApi, analytics, properties) redrawer = renderFactory.createRedrawer(this, renderApi, analytics, properties)
redrawer?.syncSize() redrawer?.syncSize()
} catch (e: RenderException) { } catch (e: RenderException) {
Logger.warn("Fallback to next API: ${e.message}") Logger.warn(e) { "Fallback to next API" }
thrown = true thrown = true
} }
} while (thrown && fallbackRenderApiQueue.isNotEmpty()) } while (thrown && fallbackRenderApiQueue.isNotEmpty())
...@@ -365,6 +369,7 @@ actual open class SkiaLayer internal constructor( ...@@ -365,6 +369,7 @@ actual open class SkiaLayer internal constructor(
} }
override fun doLayout() { override fun doLayout() {
Logger.debug { "doLayout on $this" }
backedLayer.setBounds(0, 0, roundSize(width), roundSize(height)) backedLayer.setBounds(0, 0, roundSize(width), roundSize(height))
backedLayer.validate() backedLayer.validate()
redrawer?.syncSize() redrawer?.syncSize()
...@@ -372,6 +377,7 @@ actual open class SkiaLayer internal constructor( ...@@ -372,6 +377,7 @@ actual open class SkiaLayer internal constructor(
override fun paint(g: java.awt.Graphics) { override fun paint(g: java.awt.Graphics) {
Logger.debug { "Paint called on: $this" }
checkContentScale() checkContentScale()
// `paint` can be called when we already inside `draw` method. // `paint` can be called when we already inside `draw` method.
...@@ -524,6 +530,8 @@ actual open class SkiaLayer internal constructor( ...@@ -524,6 +530,8 @@ actual open class SkiaLayer internal constructor(
check(isEventDispatchThread()) { "Method should be called from AWT event dispatch thread" } check(isEventDispatchThread()) { "Method should be called from AWT event dispatch thread" }
check(!isDisposed) { "SkiaLayer is disposed" } check(!isDisposed) { "SkiaLayer is disposed" }
checkContentScale()
FrameWatcher.nextFrame() FrameWatcher.nextFrame()
fpsCounter?.tick() fpsCounter?.tick()
...@@ -566,7 +574,7 @@ actual open class SkiaLayer internal constructor( ...@@ -566,7 +574,7 @@ actual open class SkiaLayer internal constructor(
// ignore // ignore
} catch (e: RenderException) { } catch (e: RenderException) {
if (!isDisposed) { if (!isDisposed) {
Logger.warn("Exception in draw scope: ${e.message}") Logger.warn(e) { "Exception in draw scope" }
findNextWorkingRenderApi() findNextWorkingRenderApi()
redrawer?.redrawImmediately() redrawer?.redrawImmediately()
} }
......
...@@ -21,11 +21,11 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : JvmContextHandler(laye ...@@ -21,11 +21,11 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : JvmContextHandler(laye
if (context == null) { if (context == null) {
context = directXRedrawer.makeContext() context = directXRedrawer.makeContext()
if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { if (System.getProperty("skiko.hardwareInfo.enabled") == "true") {
Logger.info("Renderer info:\n ${rendererInfo()}") Logger.info { "Renderer info:\n ${rendererInfo()}" }
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Logger.warn("${e.message}\n Failed to create Skia Direct3D context!") Logger.warn(e) { "Failed to create Skia Direct3D context!" }
return false return false
} }
return true return true
......
...@@ -26,7 +26,7 @@ internal class DirectSoftwareContextHandler(layer: SkiaLayer) : JvmContextHandle ...@@ -26,7 +26,7 @@ internal class DirectSoftwareContextHandler(layer: SkiaLayer) : JvmContextHandle
override fun initContext(): Boolean { override fun initContext(): Boolean {
if (!isInited) { if (!isInited) {
if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { if (System.getProperty("skiko.hardwareInfo.enabled") == "true") {
Logger.info("Renderer info:\n ${rendererInfo()}") Logger.info { "Renderer info:\n ${rendererInfo()}" }
} }
isInited = true isInited = true
} }
......
...@@ -15,11 +15,11 @@ internal class MetalContextHandler(layer: SkiaLayer) : JvmContextHandler(layer) ...@@ -15,11 +15,11 @@ internal class MetalContextHandler(layer: SkiaLayer) : JvmContextHandler(layer)
if (context == null) { if (context == null) {
context = metalRedrawer.makeContext() context = metalRedrawer.makeContext()
if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { if (System.getProperty("skiko.hardwareInfo.enabled") == "true") {
Logger.info("Renderer info:\n ${rendererInfo()}") Logger.info { "Renderer info:\n ${rendererInfo()}" }
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Logger.warn("${e.message}\nFailed to create Skia Metal context!") Logger.warn(e) { "Failed to create Skia Metal context!" }
return false return false
} }
return true return true
......
...@@ -9,11 +9,11 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : JvmContextHandler(layer) ...@@ -9,11 +9,11 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : JvmContextHandler(layer)
if (context == null) { if (context == null) {
context = makeGLContext() context = makeGLContext()
if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { if (System.getProperty("skiko.hardwareInfo.enabled") == "true") {
Logger.info("Renderer info:\n ${rendererInfo()}") Logger.info { "Renderer info:\n ${rendererInfo()}" }
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Logger.warn("${e.message}\nFailed to create Skia OpenGL context!") Logger.warn(e) { "Failed to create Skia OpenGL context!" }
return false return false
} }
return true return true
......
...@@ -39,7 +39,7 @@ internal class SoftwareContextHandler(layer: SkiaLayer) : JvmContextHandler(laye ...@@ -39,7 +39,7 @@ internal class SoftwareContextHandler(layer: SkiaLayer) : JvmContextHandler(laye
// Raster does not need context // Raster does not need context
if (!isInited) { if (!isInited) {
if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { if (System.getProperty("skiko.hardwareInfo.enabled") == "true") {
Logger.info("Renderer info:\n ${rendererInfo()}") Logger.info { "Renderer info:\n ${rendererInfo()}" }
} }
isInited = true isInited = true
} }
......
...@@ -127,16 +127,16 @@ internal class MetalRedrawer( ...@@ -127,16 +127,16 @@ internal class MetalRedrawer(
val rootPane = getRootPane(layer) val rootPane = getRootPane(layer)
val globalPosition = convertPoint(layer, layer.x, layer.y, rootPane) val globalPosition = convertPoint(layer, layer.x, layer.y, rootPane)
setContentScale(device, layer.contentScale) setContentScale(device, layer.contentScale)
resizeLayers( val x = globalPosition.x
device, val y = rootPane.height - globalPosition.y - layer.height
globalPosition.x, val width = layer.width.coerceAtLeast(0)
rootPane.height - globalPosition.y - layer.height, val height = layer.height.coerceAtLeast(0)
layer.width.coerceAtLeast(0), Logger.debug { "MetalRedrawer#resizeLayers $this $x $y $width $height" }
layer.height.coerceAtLeast(0) resizeLayers(device, x, y, width, height)
)
} }
override fun setVisible(isVisible: Boolean) { override fun setVisible(isVisible: Boolean) {
Logger.debug { "MetalRedrawer#setVisible $this $isVisible" }
setLayerVisible(device, isVisible) setLayerVisible(device, isVisible)
} }
......
package org.jetbrains.skiko package org.jetbrains.skiko
interface SkikoLoggerInterface {
val isTraceEnabled: Boolean
val isDebugEnabled: Boolean
val isInfoEnabled: Boolean
val isWarnEnabled: Boolean
val isErrorEnabled: Boolean
fun trace(message: String)
fun debug(message: String)
fun info(message: String)
fun warn(message: String)
fun error(message: String)
fun trace(t: Throwable, message: String)
fun debug(t: Throwable, message: String)
fun info(t: Throwable, message: String)
fun warn(t: Throwable, message: String)
fun error(t: Throwable, message: String)
}
fun setupSkikoLoggerFactory(createLogger: () -> SkikoLoggerInterface) {
Logger.loggerFactory = createLogger
}
internal object DefaultConsoleLogger: SkikoLoggerInterface {
override val isTraceEnabled: Boolean
get() = false
override val isDebugEnabled: Boolean
get() = false
override val isInfoEnabled: Boolean
get() = true
override val isWarnEnabled: Boolean
get() = true
override val isErrorEnabled: Boolean
get() = true
override fun trace(message: String) {
println("[SKIKO] trace: $message")
}
override fun trace(t: Throwable, message: String) {
println("[SKIKO] trace: $message")
println(t)
}
override fun debug(message: String) {
println("[SKIKO] debug: $message")
}
override fun debug(t: Throwable, message: String) {
println("[SKIKO] debug: $message")
println(t)
}
override fun info(message: String) {
println("[SKIKO] info: $message")
}
override fun info(t: Throwable, message: String) {
println("[SKIKO] info: $message")
println(t)
}
override fun warn(message: String) {
println("[SKIKO] warn: $message")
}
override fun warn(t: Throwable, message: String) {
println("[SKIKO] warn: $message")
println(t)
}
override fun error(message: String) {
println("[SKIKO] error: $message")
}
override fun error(t: Throwable, message: String) {
println("[SKIKO] error: $message")
println(t)
}
}
internal object Logger { internal object Logger {
fun info(msg: String) { var loggerFactory: () -> SkikoLoggerInterface = { DefaultConsoleLogger }
println("[SKIKO] info: $msg")
val loggerImpl by lazy {
loggerFactory()
}
inline fun trace(msg: () -> String) {
if (loggerImpl.isTraceEnabled) {
loggerImpl.trace(msg())
}
}
inline fun debug(msg: () -> String) {
if (loggerImpl.isDebugEnabled) {
loggerImpl.debug(msg())
}
}
inline fun info(msg: () -> String) {
if (loggerImpl.isInfoEnabled) {
loggerImpl.info(msg())
}
}
inline fun warn(msg: () -> String) {
if (loggerImpl.isWarnEnabled) {
loggerImpl.warn(msg())
}
} }
fun warn(msg: String) { inline fun error(msg: () -> String) {
println("[SKIKO] warn: $msg") if (loggerImpl.isErrorEnabled) {
loggerImpl.error(msg())
}
} }
fun error(msg: String) { inline fun trace(t: Throwable, msg: () -> String) {
println("[SKIKO] error: $msg") if (loggerImpl.isTraceEnabled) {
loggerImpl.trace(t, msg())
}
}
inline fun debug(t: Throwable, msg: () -> String) {
if (loggerImpl.isDebugEnabled) {
loggerImpl.debug(t, msg())
}
}
inline fun info(t: Throwable, msg: () -> String) {
if (loggerImpl.isInfoEnabled) {
loggerImpl.info(t, msg())
}
}
inline fun warn(t: Throwable, msg: () -> String) {
if (loggerImpl.isWarnEnabled) {
loggerImpl.warn(t, msg())
}
}
inline fun error(t: Throwable, msg:() -> String) {
if (loggerImpl.isErrorEnabled) {
loggerImpl.error(t, msg())
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment