diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 57db0774..69e99868 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -3183,6 +3183,7 @@ namespace MobileGL::MG_Backend::DirectGLES { case MG_Pipe::MGPipeResourceTarget::Tex2DMSArray: return TextureTarget::Texture2DMultisampleArray; case MG_Pipe::MGPipeResourceTarget::TexRect: return TextureTarget::TextureRectangle; case MG_Pipe::MGPipeResourceTarget::TexBuffer: return TextureTarget::TextureBuffer; + case MG_Pipe::MGPipeResourceTarget::TexExternalOES: return TextureTarget::TextureExternalOES; default: return TextureTarget::Unknown; } } diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index 463829f5..1d1008ad 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -1879,6 +1879,9 @@ namespace MobileGL::MG_Backend::DirectGLES { return TextureTarget::Texture2D; case TextureTarget::Texture1DArray: return TextureTarget::Texture2DArray; + // An external texture's storage is an imported EGLImage; to the driver it is 2D. + case TextureTarget::TextureExternalOES: + return TextureTarget::Texture2D; default: return target; } diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index 32a4072d..ed1dee3d 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -618,7 +618,9 @@ namespace MobileGL::MG_Impl::GLImpl { const auto expectedTextureTarget = MG_Util::ConvertTextureUploadTargetToTextureTarget(textureUploadTarget); if (expectedTextureTarget == TextureTarget::Unknown || - textureObject->GetTarget() != expectedTextureTarget) { + (textureObject->GetTarget() != expectedTextureTarget && + !(textureObject->GetTarget() == TextureTarget::TextureExternalOES && + expectedTextureTarget == TextureTarget::Texture2D))) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, MakeUnique( @@ -1389,7 +1391,9 @@ namespace MobileGL::MG_Impl::GLImpl { const auto expectedTextureTarget = MG_Util::ConvertTextureUploadTargetToTextureTarget(textureUploadTarget); if (expectedTextureTarget == TextureTarget::Unknown || - textureObject->GetTarget() != expectedTextureTarget) { + (textureObject->GetTarget() != expectedTextureTarget && + !(textureObject->GetTarget() == TextureTarget::TextureExternalOES && + expectedTextureTarget == TextureTarget::Texture2D))) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, MakeUnique( @@ -1539,7 +1543,9 @@ namespace MobileGL::MG_Impl::GLImpl { const auto expectedTextureTarget = MG_Util::ConvertTextureUploadTargetToTextureTarget(textureUploadTarget); if (expectedTextureTarget == TextureTarget::Unknown || - textureObject->GetTarget() != expectedTextureTarget) { + (textureObject->GetTarget() != expectedTextureTarget && + !(textureObject->GetTarget() == TextureTarget::TextureExternalOES && + expectedTextureTarget == TextureTarget::Texture2D))) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, MakeUnique( diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObject2D.cpp b/MobileGL/MG_State/GLState/TextureState/TextureObject2D.cpp index 2ec90c79..9632f1ba 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObject2D.cpp +++ b/MobileGL/MG_State/GLState/TextureState/TextureObject2D.cpp @@ -14,6 +14,9 @@ namespace MobileGL { TextureObject2D::TextureObject2D(Uint externalIndex) : TextureObjectWithOneMipmap(TextureTarget::Texture2D, externalIndex) {} + TextureObject2D::TextureObject2D(Uint externalIndex, TextureTarget target) + : TextureObjectWithOneMipmap(target, externalIndex) {} + Uint TextureObject2D::GetIndexOfTextureUploadTarget(TextureUploadTarget target) const { MOBILEGL_ASSERT(target == TextureUploadTarget::Texture2D || target == TextureUploadTarget::ProxyTexture2D, diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObject2D.h b/MobileGL/MG_State/GLState/TextureState/TextureObject2D.h index ecb009f0..f5ecc65d 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObject2D.h +++ b/MobileGL/MG_State/GLState/TextureState/TextureObject2D.h @@ -15,6 +15,9 @@ namespace MobileGL { class TextureObject2D : public TextureObjectWithOneMipmap { public: explicit TextureObject2D(Uint externalIndex); + // An external texture (GL_TEXTURE_EXTERNAL_OES) is a 2D texture whose storage is an + // imported EGLImage; it keeps that target so the render server can tell it apart. + TextureObject2D(Uint externalIndex, TextureTarget target); const Vector& GetUploadTargets() const override { return m_uploadTargets; } protected: diff --git a/MobileGL/MG_State/GLState/TextureState/TextureState.cpp b/MobileGL/MG_State/GLState/TextureState/TextureState.cpp index 60d249d5..076d1c30 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureState.cpp +++ b/MobileGL/MG_State/GLState/TextureState/TextureState.cpp @@ -35,6 +35,14 @@ namespace MobileGL::MG_State::GLState { return MakeShared(index); case TextureTarget::Texture2D: return MakeShared(index); + // GL_TEXTURE_EXTERNAL_OES: an external texture IS a 2D texture whose storage comes from an + // imported EGLImage (the compositor's display-daemon dma-buf). The object is the 2D one; what + // differs is where the storage comes from, and the import path records that. Without this row + // the factory asserted "Unimplemented texture type when creating texture object!" the moment + // kwin bound one (measured: the compositor died on Trace/breakpoint trap right after the bind + // was accepted). + case TextureTarget::TextureExternalOES: + return MakeShared(index, TextureTarget::TextureExternalOES); case TextureTarget::Texture3D: return MakeShared(index); case TextureTarget::TextureBuffer: diff --git a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp index bea1d21e..ee3c038a 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp @@ -404,6 +404,14 @@ namespace MobileGL { return TextureUploadTarget::Texture1D; case GL_TEXTURE_2D: return TextureUploadTarget::Texture2D; + // GL_TEXTURE_EXTERNAL_OES (0x8D65), an upload target of its own right: the compositor + // attaches the imported dma-buf texture to a framebuffer through this enum, and the attach + // path validates the target here. Left unmapped it became Unknown, the validation failed, + // the attachment was never recorded, and the compositor's own check then read + // GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT. External textures ARE two-dimensional, so + // the upload target is the 2D one. + case 0x8D65: + return TextureUploadTarget::Texture2D; case GL_TEXTURE_3D: return TextureUploadTarget::Texture3D; case GL_PROXY_TEXTURE_2D: