为啥我使用大于 12.02 的 JAVAFX 版本会得到 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
Posted
技术标签:
【中文标题】为啥我使用大于 12.02 的 JAVAFX 版本会得到 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT【英文标题】:Why do do I get GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT using JAVAFX versions greater than 12.02为什么我使用大于 12.02 的 JAVAFX 版本会得到 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 【发布时间】:2021-03-18 18:56:06 【问题描述】:我使用 BASE20(即 Ubuntu 20.04)作为目标操作系统构建了一个基于 LINUX 的 UBUNTU snap 应用程序,它正在分发中。
该应用程序在 OpenJFX 11 和 12 上使用 OpenJDK 11 到 15.0.1 运行良好。但是,如果我移动到更新版本的 OpenJFX,每次屏幕更改都会出现以下错误(舞台上的场景更改) ) - 屏幕变为空白,终端上显示以下错误:
Incomplete attachment. (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)(FBO - 820)
Error creating framebuffer object with TexID 1).
如果我强制重写屏幕(例如,通过切换到终端窗口或另一个应用程序,然后返回我的应用程序),屏幕就会显示预期的内容。
这似乎是后续 JAVAFX 版本中的一个错误 - 但是在 snap 中包含的 UBUNTU 20.04 库中可能缺少某些内容。我会在 Snapcraft 网站上发布类似的帮助请求,但也许这里有人遇到了类似的问题,可能会有一些建议。
我的开发环境是 IntelliJ Idea,使用 gradle 和 openJDK 15。
提前致谢
艾伦
编辑: 我已经设法对我自己的代码进行了一些跟踪并进入了 java 库源代码。
错误发生在文件 Scene.java 中此方法执行的最后一行之后 - 有一件事 - 应用程序不会崩溃,它会以空白屏幕运行,直到某些东西强制屏幕刷新,例如打开另一个全屏应用程序,然后再次关闭它 - 然后出现所需的场景!
第一行在 Scene.java 的第 2578 行
//==
@Override
public void mouseEvent(EventType<MouseEvent> type, double x, double y, double screenX, double screenY,
MouseButton button, boolean popupTrigger, boolean synthesized,
boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown,
boolean primaryDown, boolean middleDown, boolean secondaryDown,
boolean backDown, boolean forwardDown)
MouseEvent mouseEvent = new MouseEvent(type, x, y, screenX, screenY, button,
0, // click count will be adjusted by clickGenerator later anyway
shiftDown, controlDown, altDown, metaDown,
primaryDown, middleDown, secondaryDown, backDown, forwardDown,
synthesized, popupTrigger, false, null);
processMouseEvent(mouseEvent);
//===========================================================================
错误前的堆栈:
//====
mouseEvent:2591, Scene$ScenePeerListener (javafx.scene)
run:409, GlassViewEventHandler$MouseEventNotification (com.sun.javafx.tk.quantum)
run:299, GlassViewEventHandler$MouseEventNotification (com.sun.javafx.tk.quantum)
doPrivileged:-1, AccessController (java.security)
lambda$handleMouseEvent$2:447, GlassViewEventHandler (com.sun.javafx.tk.quantum)
get:-1, 2067987277 (com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$812)
runWithoutRenderLock:412, QuantumToolkit (com.sun.javafx.tk.quantum)
handleMouseEvent:446, GlassViewEventHandler (com.sun.javafx.tk.quantum)
handleMouseEvent:556, View (com.sun.glass.ui)
notifyMouse:942, View (com.sun.glass.ui)
_runLoop:-1, GtkApplication (com.sun.glass.ui.gtk)
lambda$runLoop$11:277, GtkApplication (com.sun.glass.ui.gtk)
run:-1, 1159114532 (com.sun.glass.ui.gtk.GtkApplication$$Lambda$115)
run:834, Thread (java.lang)
//============================================================================
应用代码调用栈:
//==
private void setupStage()
mLastTitle = mPrimaryStage.getTitle();
mPrimaryStage.setScene(mScene);
mPrimaryStage.setTitle("PhotoNoteBook" + MyConstants.TMMARK + " Photo Carousel");
mPrimaryStage.show();
//===
上述方法被调用:
//==
public PhotoCarousel(ImageContainerCallBack imageContainerCallBack, Stage primaryStage, Scene lastScene, UUID photoNotebookUuid, int imageNumber)
DEBUG = (MyLogger.getTraceLevel() == MyLogger.TRACELEVELDEBUG);
MyLogger.Logi(this.getClass(), " - Method: PhotoCarousel",
"Message: Starting constructor ", "");
mImageContainerCallback = imageContainerCallBack;
mPrimaryStage = primaryStage;
mLastScene = lastScene;
mPhotoNotebookUuid = photoNotebookUuid;
mImageNumber = imageNumber;
mPhotoNotebookDataList = PhotoNotebookDataList.get();
setUpScene();
setupStage();
//==
注意上述方法中的 setupscene() 是一种创建场景的方法,在 JAVAFX 11.0.2 -> 11.0.5 中可以正常工作 上面的方法被调用:
//===
private void openPhotoCarouselButtonClickHandler()
mOpenPhotoCarouselButton.setStyle("-fx-background-color:MediumSeaGreen");
if ((mPhotoNotebookUuid != null) && (photosToWorkWith()))
PhotoCarousel photoCarousel = new PhotoCarousel(this,
mPrimaryStage, mScene, mPhotoNotebookUuid, 0);
resetButtonColours();
//===
下一个代码片段是创建按钮并将它们放置在工具栏上的方法的一部分。片段中描述的按钮使用 lambda 设置按钮 setOnAction 变量
上述方法被调用:
//===
.
.
.
mOpenPhotoCarouselButton = new Button();
mOpenPhotoCarouselButton.setOnAction(e -> openPhotoCarouselButtonClickHandler());
mOpenPhotoCarouselButton.setPrefWidth(buttonWidth);
mOpenPhotoCarouselButton.setText("Photos");
.
.
//===
我的 build.gradle
plugins
id 'org.openjfx.javafxplugin' version '0.0.9'
plugins
id 'java'
id 'application'
id "org.beryx.jlink" version "2.22.0"
repositories
mavenCentral()
jcenter()
google()
jlink
options=['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
launcher
name = 'photonotebook'
group 'com.dryjointproductions.photonotebook'
version '1.4.2'
allprojects
apply plugin: 'idea'
idea.module.outputDir file("out/production/classes")
allprojects
tasks.withType(JavaCompile)
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
sourceSets
main
resources
srcDirs += sourceSets.main.java.srcDirs + sourceSets.main.resources.srcDirs + 'resources'
exclude '**/*.java'
javafx
version = "13.0.2"
modules = ['javafx.controls', 'javafx.graphics', 'javafx.base','javafx.fxml', 'javafx.swing', 'javafx.web' ]
compileJava
sourceCompatibility = 11
plugins.withType(JavaPlugin).configureEach
java
modularity.inferModulePath = true
application
setMainModule ('PhotoNoteBook')
setMainClassName('com.dryjointproductions.photonotebook.PhotoNoteBook')
dependencies
// implementation 'com.google.code.gson:gson:2.7'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'org.xerial:sqlite-jdbc:3.28.0'
implementation group: 'javax.activation', name: 'activation', version: '1.1.1'
implementation group: 'javax.mail', name: 'mail', version: '1.4.7'
implementation 'com.drewnoakes:metadata-extractor:2.14.0'
implementation 'net.coobird:thumbnailator:0.4.12'
如果我能找到方法,我会尝试提交错误报告!同时,如果有人能找到我的 Java 问题,我将不胜感激!
【问题讨论】:
您可以尝试设置一些系统属性以查看是否可以获得更多信息:例如 prism.debug=true prism.verbose=true 之前出现过与分配纹理相关的 OpenGL 错误。 bugs.openjdk.java.net/browse/JDK-8123050 bugs.openjdk.java.net/browse/JDK-8088510 如果您有可重现的测试用例,我强烈建议您提交错误报告。 正在修复错误:bugs.openjdk.java.net/browse/… swpalmer - 因为这个错误仍然存在于 JAVAFX17 中,所以我又使用了 -Djavafx.verbose=true -Djavafx.debug=true -Dprism.verbose=true -Dprism.debug=true - Dquantum.verbose=true -Dquantum.debug=true -Dquantum.pulsedebug=true -Dprism.order=sw,这引发了一些有趣的错误。 【参考方案1】:我终于找到了这个错误的根源,但只是作为一种解决方法,所以对于遇到这个问题的其他人来说,这可能会有所帮助。
我使用以下 jvm 调试选项运行该应用程序:
-Djavafx.verbose=true -Djavafx.debug=true -Dprism.verbose=true -Dprism.debug=true -Dquantum.verbose=true -Dquantum.debug=true -Dquantum.pulsedebug=true -Dprism.order=sw
后一个选项暴露了一个问题,一个崩溃:
PC.removeDirtyScene: scene: 1596154225 @ (-1,-1)
PC.removeDirtyScene: scene: 1596154225 @ (-1,-1)
PC.removeDirtyScene: scene: 1596154225 @ (-1,-1)
PC.removeDirtyScene: scene: 1596154225 @ (-1,-1)
PC.addDirtyScene: 12225757175188 scene: 1596154225 @ (-1,-1)
QT.postPulse@(12225760218463): TAPN
PC.addDirtyScene: 12225781351419 scene: 1596154225 @ (-1,-1)
PC.addDirtyScene: 12225781509215 scene: 1596154225 @ (-1,-1)
PC.addDirtyScene: 12225782656044 scene: 1596154225 @ (-1,-1)
QT.endPulse: 12225782846730
java.lang.IllegalArgumentException: WIDTH must be positive
at javafx.graphics/com.sun.pisces.AbstractSurface.<init>(Unknown Source)
at javafx.graphics/com.sun.pisces.JavaSurface.<init>(Unknown Source)
at javafx.graphics/com.sun.prism.sw.SWRTTexture.<init>(Unknown Source)
at javafx.graphics/com.sun.prism.sw.SWResourceFactory.createRTTexture(Unknown Source)
at javafx.graphics/com.sun.prism.sw.SWResourceFactory.createRTTexture(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.UploadingPainter.run(Unknown Source)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.RenderJob.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
QT.postPulse@(12225783499118): TaPN
PC.addDirtyScene: 12225786804608 scene: 1596154225 @ (-1,-1)
QT.endPulse: 12225786976417
这让我开始思考......如果我在调用 stage.show() 之前设置舞台的宽度和高度,这可能会消失,而且确实如此。 例如
Stage mPrimaryStage ;
ScreenUtils screenUtils = new ScreenUtils();
double minX = screenUtils.getMinX();
double minY = screenUtils.getMinY();
double height = screenUtils.getScreenHeight();
double width = screenUtils.getScreenWidth();
mPrimaryStage.setX(minX);
mPrimaryStage.setY(minY);
mPrimaryStage.setWidth(width);
mPrimaryStage.setHeight(height);
mPrimaryStage.show();
(ScreenUtils 是我创建的用于获取屏幕信息的实用程序)
错误“附件不完整。(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)(FBO - 820)”和“创建 TexID 1 的帧缓冲区对象时出错” 不再报告。
此解决方法已报告给 OpenJDK 错误报告。
谢谢大家
艾伦
【讨论】:
以上是关于为啥我使用大于 12.02 的 JAVAFX 版本会得到 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT的主要内容,如果未能解决你的问题,请参考以下文章
Javafx怎么播放flash,就是我用Java main函数执行,直接调用Javafx做好的页面,为啥不能播放flash