From 75d34ab585a06ab2210ac1a9fee48c7bc1d914d0 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Thu, 23 Jul 2020 19:15:34 +0900 Subject: [PATCH] graphicsdriver/opengl: Forbids PBO on Raspberry Pi 4 (#1261) Fixes #1208 --- .../graphicsdriver/opengl/context_desktop.go | 16 ++++++- .../graphicsdriver/opengl/context_notx.go | 21 +++++++++ internal/graphicsdriver/opengl/context_x.go | 46 +++++++++++++++++++ .../graphicsdriver/opengl/gl/package_x.go | 32 +++++++++++++ 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 internal/graphicsdriver/opengl/context_notx.go create mode 100644 internal/graphicsdriver/opengl/context_x.go create mode 100644 internal/graphicsdriver/opengl/gl/package_x.go diff --git a/internal/graphicsdriver/opengl/context_desktop.go b/internal/graphicsdriver/opengl/context_desktop.go index 06b35108d..08b23d9e0 100644 --- a/internal/graphicsdriver/opengl/context_desktop.go +++ b/internal/graphicsdriver/opengl/context_desktop.go @@ -546,11 +546,23 @@ func (c *context) needsRestoring() bool { } func (c *context) canUsePBO() bool { - return true + var available bool + _ = c.t.Call(func() error { + available = isPBOAvailable() + return nil + }) + + return available } func (c *context) texSubImage2D(t textureNative, width, height int, args []*driver.ReplacePixelsArgs) { - panic("opengl: texSubImage2D is not implemented on this environment") + c.bindTexture(t) + _ = c.t.Call(func() error { + for _, a := range args { + gl.TexSubImage2D(gl.TEXTURE_2D, 0, int32(a.X), int32(a.Y), int32(a.Width), int32(a.Height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(a.Pixels)) + } + return nil + }) } func (c *context) newPixelBufferObject(width, height int) buffer { diff --git a/internal/graphicsdriver/opengl/context_notx.go b/internal/graphicsdriver/opengl/context_notx.go new file mode 100644 index 000000000..0521c85d5 --- /dev/null +++ b/internal/graphicsdriver/opengl/context_notx.go @@ -0,0 +1,21 @@ +// Copyright 2020 The Ebiten Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build js !freebsd,!linux + +package opengl + +func isPBOAvailable() bool { + return true +} diff --git a/internal/graphicsdriver/opengl/context_x.go b/internal/graphicsdriver/opengl/context_x.go new file mode 100644 index 000000000..60f4b0970 --- /dev/null +++ b/internal/graphicsdriver/opengl/context_x.go @@ -0,0 +1,46 @@ +// Copyright 2020 The Ebiten Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !js +// +build freebsd linux + +package opengl + +import ( + "strings" + "sync" + + "github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl/gl" +) + +var ( + pboAvailable = true + pboAvailableOnce sync.Once +) + +func isPBOAvailable() bool { + pboAvailableOnce.Do(func() { + // This must be called after GL context is created. + str := gl.RendererDeviceString() + tokens := strings.Split(str, " ") + if len(tokens) == 0 { + return + } + // Raspbery Pi 4 has an issue around PBO (#1208). + if tokens[0] == "V3D" { + pboAvailable = false + } + }) + return pboAvailable +} diff --git a/internal/graphicsdriver/opengl/gl/package_x.go b/internal/graphicsdriver/opengl/gl/package_x.go new file mode 100644 index 000000000..26c2a9c97 --- /dev/null +++ b/internal/graphicsdriver/opengl/gl/package_x.go @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT + +// +build !js +// +build freebsd linux + +package gl + +// #include +// +// static const char* RendererDeviceString() { +// #ifdef GLX_MESA_query_renderer +// static PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC queryString; +// if (!queryString) { +// queryString = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) +// glXGetProcAddressARB((const GLubyte *)"glXQueryCurrentRendererStringMESA"); +// } +// +// static const char* rendererDevice; +// if (!rendererDevice) { +// rendererDevice = queryString(GLX_RENDERER_DEVICE_ID_MESA); +// } +// +// return rendererDevice; +// #else +// return ""; +// #endif +// } +import "C" + +func RendererDeviceString() string { + return C.GoString(C.RendererDeviceString()) +}