mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
Merge branch 'Feat/Backend-Direct-GLES' into dev
This commit is contained in:
@@ -8,8 +8,11 @@
|
||||
|
||||
#include "DirectGLES.h"
|
||||
#include "GLES3/gl32.h"
|
||||
#include "MG_State/GLState/ErrorState/Error.h"
|
||||
#include "MG_State/GLState/RenderState/RenderState.h"
|
||||
#include "MG_State/GLState/SamplerState/SamplerObject.h"
|
||||
#include "MG_Util/Debug/Log.h"
|
||||
#include "MG_Util/Types.h"
|
||||
#include "Utils.h"
|
||||
#include "Managers.h"
|
||||
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
|
||||
@@ -882,8 +885,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
auto textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
||||
if (!TextureImpl::IsSupportedTextureTarget(textureTarget)) {
|
||||
MOBILEGL_ASSERT(false, " Texture target %s is not supported, skipping.",
|
||||
MG_Util::ConvertTextureTargetToString(textureTarget).c_str());
|
||||
MGLOG_E(" Texture target %s is not supported, skipping.",
|
||||
MG_Util::ConvertTextureTargetToString(textureTarget).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -909,26 +912,40 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
|
||||
static GLuint s_prevDrawFBO = 0;
|
||||
void BindTempDrawFBO() {
|
||||
static GLuint s_prevReadFBO = 0;
|
||||
void BindTempFBO(Bool isRead) {
|
||||
MGLOG_D("%s: Binding temporary FBO for operations like CopyTexImage2D that require framebuffer binding, "
|
||||
"previous draw FBO=%u",
|
||||
__func__, s_prevDrawFBO);
|
||||
"previous draw FBO=%u, read FBO=%u",
|
||||
__func__, s_prevDrawFBO, s_prevReadFBO);
|
||||
static GLuint tempFBO = 0;
|
||||
if (!tempFBO) {
|
||||
MG_External::GLES::glGenFramebuffers(1, &tempFBO);
|
||||
}
|
||||
MG_External::GLES::glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&s_prevDrawFBO);
|
||||
MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFBO);
|
||||
if (isRead) {
|
||||
MG_External::GLES::glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&s_prevReadFBO);
|
||||
MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFBO);
|
||||
} else {
|
||||
MG_External::GLES::glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&s_prevDrawFBO);
|
||||
MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFBO);
|
||||
}
|
||||
}
|
||||
void RestoreDrawFBOFromTemp() {
|
||||
MGLOG_D("%s: Restoring previous draw FBO=%u", __func__, s_prevDrawFBO);
|
||||
MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_prevDrawFBO);
|
||||
void RestoreFBOFromTemp(Bool isRead) {
|
||||
if (isRead) {
|
||||
MGLOG_D("%s: Restoring previous read FBO=%u", __func__, s_prevReadFBO);
|
||||
MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, s_prevReadFBO);
|
||||
} else {
|
||||
MGLOG_D("%s: Restoring previous draw FBO=%u", __func__, s_prevDrawFBO);
|
||||
MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_prevDrawFBO);
|
||||
}
|
||||
}
|
||||
|
||||
class TempFBOBinder {
|
||||
public:
|
||||
TempFBOBinder() { BindTempDrawFBO(); }
|
||||
~TempFBOBinder() { RestoreDrawFBOFromTemp(); }
|
||||
TempFBOBinder(Bool isRead) : m_isRead(isRead) { BindTempFBO(isRead); }
|
||||
~TempFBOBinder() { RestoreFBOFromTemp(m_isRead); }
|
||||
|
||||
private:
|
||||
const Bool m_isRead = false;
|
||||
};
|
||||
|
||||
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||
@@ -1001,7 +1018,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
});
|
||||
|
||||
GLenum attachment = isStencilFormat ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||
TempFBOBinder tempFBOBinder;
|
||||
TempFBOBinder tempFBOBinder(false);
|
||||
MG_External::GLES::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level);
|
||||
|
||||
if (MG_External::GLES::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
@@ -1080,7 +1097,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||
});
|
||||
GLenum attachment = isStencilFormat ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||
TempFBOBinder tempFBOBinder;
|
||||
TempFBOBinder tempFBOBinder(false);
|
||||
MG_External::GLES::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level);
|
||||
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) {
|
||||
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||
@@ -1136,6 +1153,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
MG_External::GLES::glClearBufferfv(buffer, drawbuffer, value);
|
||||
}
|
||||
|
||||
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
|
||||
TextureImpl::SyncNeccessaryTextures();
|
||||
FramebufferImpl::SyncCurrentFBO();
|
||||
@@ -1154,4 +1172,289 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_External::GLES::glClearBufferuiv(buffer, drawbuffer, value);
|
||||
}
|
||||
|
||||
} // namespace MobileGL::MG_Backend::DirectGLES
|
||||
class TempPixelStoreParameterSync {
|
||||
public:
|
||||
TempPixelStoreParameterSync(Bool isUnpack) : m_isUnpack(isUnpack) {
|
||||
const auto& currentParams = MG_State::pGLContext->GetPixelStoreParameters(isUnpack);
|
||||
m_prevParams = QueryCurrentGLPixelStoreParams(isUnpack);
|
||||
Sync(isUnpack, currentParams);
|
||||
}
|
||||
|
||||
~TempPixelStoreParameterSync() { Sync(m_isUnpack, m_prevParams); }
|
||||
|
||||
private:
|
||||
const Bool m_isUnpack;
|
||||
|
||||
PixelStoreParameters m_prevParams;
|
||||
|
||||
PixelStoreParameters QueryCurrentGLPixelStoreParams(Bool isUnpack) {
|
||||
PixelStoreParameters p;
|
||||
if (!isUnpack) {
|
||||
MG_External::GLES::glGetIntegerv(GL_PACK_ALIGNMENT, (GLint*)&p.Alignment);
|
||||
MG_External::GLES::glGetIntegerv(GL_PACK_ROW_LENGTH, (GLint*)&p.RowLength);
|
||||
MG_External::GLES::glGetIntegerv(GL_PACK_SKIP_ROWS, (GLint*)&p.SkipRows);
|
||||
MG_External::GLES::glGetIntegerv(GL_PACK_SKIP_PIXELS, (GLint*)&p.SkipPixels);
|
||||
// MG_External::GLES::glGetIntegerv(GL_PACK_IMAGE_HEIGHT, (GLint*)&p.ImageHeight);
|
||||
// MG_External::GLES::glGetIntegerv(GL_PACK_SKIP_IMAGES, (GLint*)&p.SkipImages);
|
||||
// GLint tmp;
|
||||
// MG_External::GLES::glGetIntegerv(GL_PACK_SWAP_BYTES, &tmp);
|
||||
// p.SwapBytes = tmp ? true : false;
|
||||
// MG_External::GLES::glGetIntegerv(GL_PACK_LSB_FIRST, &tmp);
|
||||
// p.LSBFirst = tmp ? true : false;
|
||||
} else {
|
||||
MG_External::GLES::glGetIntegerv(GL_UNPACK_ALIGNMENT, (GLint*)&p.Alignment);
|
||||
MG_External::GLES::glGetIntegerv(GL_UNPACK_ROW_LENGTH, (GLint*)&p.RowLength);
|
||||
MG_External::GLES::glGetIntegerv(GL_UNPACK_SKIP_ROWS, (GLint*)&p.SkipRows);
|
||||
MG_External::GLES::glGetIntegerv(GL_UNPACK_SKIP_PIXELS, (GLint*)&p.SkipPixels);
|
||||
MG_External::GLES::glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, (GLint*)&p.ImageHeight);
|
||||
MG_External::GLES::glGetIntegerv(GL_UNPACK_SKIP_IMAGES, (GLint*)&p.SkipImages);
|
||||
// GLint tmp;
|
||||
// MG_External::GLES::glGetIntegerv(GL_UNPACK_SWAP_BYTES, &tmp);
|
||||
// p.SwapBytes = tmp ? true : false;
|
||||
// MG_External::GLES::glGetIntegerv(GL_UNPACK_LSB_FIRST, &tmp);
|
||||
// p.LSBFirst = tmp ? true : false;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void Sync(Bool isUnpack, const PixelStoreParameters& params) {
|
||||
if (!isUnpack) {
|
||||
MG_External::GLES::glPixelStorei(GL_PACK_ALIGNMENT, params.Alignment);
|
||||
MG_External::GLES::glPixelStorei(GL_PACK_ROW_LENGTH, params.RowLength);
|
||||
MG_External::GLES::glPixelStorei(GL_PACK_SKIP_ROWS, params.SkipRows);
|
||||
MG_External::GLES::glPixelStorei(GL_PACK_SKIP_PIXELS, params.SkipPixels);
|
||||
// MG_External::GLES::glPixelStorei(GL_PACK_IMAGE_HEIGHT, params.ImageHeight);
|
||||
// MG_External::GLES::glPixelStorei(GL_PACK_SKIP_IMAGES, params.SkipImages);
|
||||
// MG_External::GLES::glPixelStorei(GL_PACK_SWAP_BYTES, params.SwapBytes ? GL_TRUE : GL_FALSE);
|
||||
// MG_External::GLES::glPixelStorei(GL_PACK_LSB_FIRST, params.LSBFirst ? GL_TRUE : GL_FALSE);
|
||||
} else {
|
||||
MG_External::GLES::glPixelStorei(GL_UNPACK_ALIGNMENT, params.Alignment);
|
||||
MG_External::GLES::glPixelStorei(GL_UNPACK_ROW_LENGTH, params.RowLength);
|
||||
MG_External::GLES::glPixelStorei(GL_UNPACK_SKIP_ROWS, params.SkipRows);
|
||||
MG_External::GLES::glPixelStorei(GL_UNPACK_SKIP_PIXELS, params.SkipPixels);
|
||||
MG_External::GLES::glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, params.ImageHeight);
|
||||
MG_External::GLES::glPixelStorei(GL_UNPACK_SKIP_IMAGES, params.SkipImages);
|
||||
// MG_External::GLES::glPixelStorei(GL_UNPACK_SWAP_BYTES, params.SwapBytes ? GL_TRUE : GL_FALSE);
|
||||
// MG_External::GLES::glPixelStorei(GL_UNPACK_LSB_FIRST, params.LSBFirst ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
||||
MGLOG_D("ReadPixels: x=%d y=%d w=%d h=%d format=%s type=%s pixels=%p", x, y, width, height,
|
||||
MG_Util::ConvertGLEnumToString(format).c_str(), MG_Util::ConvertGLEnumToString(type).c_str(), pixels);
|
||||
|
||||
MOBILEGL_ASSERT(format == GL_RGBA || format == GL_RGBA_INTEGER,
|
||||
"Only GL_RGBA and GL_RGBA_INTEGER are supported currently, while requested %s.",
|
||||
MG_Util::ConvertGLEnumToString(format).c_str());
|
||||
MOBILEGL_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT || type == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||
type == GL_INT || type == GL_FLOAT,
|
||||
"Only GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, GL_UNSIGNED_INT_2_10_10_10_REV, "
|
||||
"GL_INT and GL_FLOAT are supported currently, while requested %s.",
|
||||
MG_Util::ConvertGLEnumToString(type).c_str());
|
||||
|
||||
MGLOG_D("ReadPixels: SyncNeccessaryTextures()");
|
||||
TextureImpl::SyncNeccessaryTextures();
|
||||
|
||||
MGLOG_D("ReadPixels: SyncCurrentFBO()");
|
||||
FramebufferImpl::SyncCurrentFBO();
|
||||
|
||||
MGLOG_D("ReadPixels: BindCurrentFBO(Read)");
|
||||
BindCurrentFBO(FramebufferTarget::Read);
|
||||
|
||||
MGLOG_D("ReadPixels: Applying TempPixelStoreParameterSync (PACK)");
|
||||
TempPixelStoreParameterSync tempPackParamsSync(false);
|
||||
|
||||
GLenum fbStatus = MG_External::GLES::glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
|
||||
MGLOG_D("ReadPixels: GL_READ_FRAMEBUFFER status = %s", MG_Util::ConvertGLEnumToString(fbStatus).c_str());
|
||||
|
||||
if (fbStatus != GL_FRAMEBUFFER_COMPLETE) {
|
||||
MGLOG_E("ReadPixels: bound READ FBO is not complete");
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle PBO
|
||||
auto pixelPackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
|
||||
Bool usePBO;
|
||||
GLuint prevPixelPackBuffer = 0;
|
||||
if (pixelPackBufferObject) {
|
||||
BufferImpl::CreateAndSyncBufferObject(pixelPackBufferObject);
|
||||
MGLOG_D("ReadPixels: Using PBO %u", pixelPackBufferObject->GetExternalIndex());
|
||||
usePBO = true;
|
||||
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(pixelPackBufferObject);
|
||||
|
||||
if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) {
|
||||
MGLOG_E("ReadPixels: No backend buffer found for PBO %u.",
|
||||
pixelPackBufferObject ? pixelPackBufferObject->GetExternalIndex() : 0);
|
||||
return;
|
||||
}
|
||||
const auto& backendBufferObject = backendBufferIt->second;
|
||||
backendBufferObject->Bind(GL_PIXEL_PACK_BUFFER);
|
||||
MG_External::GLES::glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&prevPixelPackBuffer);
|
||||
} else {
|
||||
usePBO = false;
|
||||
MGLOG_D("ReadPixels: Not using PBO");
|
||||
}
|
||||
|
||||
MGLOG_D("ReadPixels: glReadPixels()");
|
||||
MG_External::GLES::glReadPixels(x, y, width, height, format, type, pixels);
|
||||
if (usePBO) {
|
||||
// pull back to client memory if PBO is used
|
||||
MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory");
|
||||
GLvoid* pboMappedPtr = MG_External::GLES::glMapBufferRange(
|
||||
GL_PIXEL_PACK_BUFFER, 0, pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT);
|
||||
if (pboMappedPtr) {
|
||||
MGLOG_D("ReadPixels: Copying data from PBO to client memory");
|
||||
SizeT size = pixelPackBufferObject->GetSize();
|
||||
pixelPackBufferObject->UploadSubData({pboMappedPtr, size}, 0);
|
||||
pixelPackBufferObject->ClearDirty();
|
||||
MGLOG_D("ReadPixels: Unmapping PBO");
|
||||
MG_External::GLES::glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
} else {
|
||||
MGLOG_E("ReadPixels: glMapBufferRange returned nullptr");
|
||||
MGLOG_E("ReadPixels: glMapBufferRange returned nullptr");
|
||||
}
|
||||
MGLOG_D("ReadPixels: Restoring previous pixel pack buffer binding %u", prevPixelPackBuffer);
|
||||
MG_External::GLES::glBindBuffer(GL_PIXEL_PACK_BUFFER, prevPixelPackBuffer);
|
||||
}
|
||||
MGLOG_D("ReadPixels: finished");
|
||||
}
|
||||
|
||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels) {
|
||||
MGLOG_D("GetTexImage: target=%s level=%d format=%s type=%s pixels=%p",
|
||||
MG_Util::ConvertGLEnumToString(target).c_str(), level, MG_Util::ConvertGLEnumToString(format).c_str(),
|
||||
MG_Util::ConvertGLEnumToString(type).c_str(), pixels);
|
||||
|
||||
MOBILEGL_ASSERT(format == GL_RGBA || format == GL_RGBA_INTEGER,
|
||||
"Only GL_RGBA and GL_RGBA_INTEGER are supported currently, while requested %s.",
|
||||
MG_Util::ConvertGLEnumToString(format).c_str());
|
||||
MOBILEGL_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT || type == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||
type == GL_INT || type == GL_FLOAT,
|
||||
"Only GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, GL_UNSIGNED_INT_2_10_10_10_REV, "
|
||||
"GL_INT and GL_FLOAT are supported currently, while requested %s.",
|
||||
MG_Util::ConvertGLEnumToString(type).c_str());
|
||||
|
||||
MGLOG_D("GetTexImage: SyncNeccessaryTextures()");
|
||||
TextureImpl::SyncNeccessaryTextures();
|
||||
|
||||
MGLOG_D("GetTexImage: SyncCurrentFBO()");
|
||||
FramebufferImpl::SyncCurrentFBO();
|
||||
|
||||
Uint activeTextureUnit = MG_State::pGLContext->GetActiveTextureUnit();
|
||||
MGLOG_D("GetTexImage: active texture unit = %u", activeTextureUnit);
|
||||
|
||||
const auto& textureObject = MG_State::pGLContext->GetTextureUnitObject(activeTextureUnit)
|
||||
.GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target))
|
||||
.GetBoundObject();
|
||||
|
||||
MGLOG_D("GetTexImage: bound texture object = %p (name=%u)", textureObject.get(),
|
||||
textureObject ? textureObject->GetExternalIndex() : 0);
|
||||
|
||||
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
||||
|
||||
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
|
||||
MGLOG_E("GetTexImage: No backend texture found for texture %u.",
|
||||
textureObject ? textureObject->GetExternalIndex() : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint backendTexId = backendTextureIt->second->GetBackendTextureId();
|
||||
MGLOG_D("GetTexImage: backend texture id = %u", backendTexId);
|
||||
|
||||
MGLOG_D("GetTexImage: Binding temporary FBO");
|
||||
TempFBOBinder tempFBOBinder(true);
|
||||
|
||||
MGLOG_D("GetTexImage: glFramebufferTexture2D(level=%d)", level);
|
||||
MG_External::GLES::glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, backendTexId,
|
||||
level);
|
||||
MGLOG_D("GetTexImage: glReadBuffer(GL_COLOR_ATTACHMENT0)");
|
||||
MG_External::GLES::glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
GLenum fbStatus = MG_External::GLES::glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
|
||||
MGLOG_D("GetTexImage: GL_READ_FRAMEBUFFER status = %s", MG_Util::ConvertGLEnumToString(fbStatus).c_str());
|
||||
|
||||
if (fbStatus != GL_FRAMEBUFFER_COMPLETE) {
|
||||
MGLOG_E("GetTexImage: READ FBO incomplete");
|
||||
MGLOG_E("GetTexImage: bound READ FBO is not complete");
|
||||
return;
|
||||
}
|
||||
|
||||
MGLOG_D("GetTexImage: Applying TempPixelStoreParameterSync (PACK)");
|
||||
TempPixelStoreParameterSync tempPackParamsSync(false);
|
||||
|
||||
const auto& storageType = textureObject->GetStorageType();
|
||||
MGLOG_D("GetTexImage: texture storage type = %d", (int)storageType);
|
||||
|
||||
if (storageType == TextureStorageType::Buffer) {
|
||||
MGLOG_E("GetTexImage: Texture storage type Buffer is not supported.");
|
||||
MGLOG_E("GetTexImage: Texture storage type Buffer is not supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
|
||||
|
||||
auto levelRange = textureMipmapObject->GetLevelRange();
|
||||
MGLOG_D("GetTexImage: mipmap level range = [%d, %d)", levelRange.x(), levelRange.y());
|
||||
|
||||
if (level < levelRange.x() || level >= levelRange.y()) {
|
||||
MGLOG_E("GetTexImage: Requested level %d out of range", level);
|
||||
MOBILEGL_ASSERT(false,
|
||||
"GetTexImage: Requested level %d is out of range "
|
||||
"(base level %d, max level %d).",
|
||||
level, levelRange.x(), levelRange.y());
|
||||
return;
|
||||
}
|
||||
|
||||
auto size = textureMipmapObject->GetMipmapTexelSize(MG_Util::ConvertGLEnumToTextureUploadTarget(target), level);
|
||||
|
||||
MGLOG_D("GetTexImage: mip level %d size = %dx%d", level, size.x(), size.y());
|
||||
|
||||
// Handle PBO
|
||||
auto pixelPackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
|
||||
Bool usePBO;
|
||||
GLuint prevPixelPackBuffer = 0;
|
||||
if (pixelPackBufferObject) {
|
||||
BufferImpl::CreateAndSyncBufferObject(pixelPackBufferObject);
|
||||
MGLOG_D("GetTexImage: Using PBO %u", pixelPackBufferObject->GetExternalIndex());
|
||||
usePBO = true;
|
||||
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(pixelPackBufferObject);
|
||||
if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) {
|
||||
MGLOG_E("GetTexImage: No backend buffer found for PBO %u.",
|
||||
pixelPackBufferObject ? pixelPackBufferObject->GetExternalIndex() : 0);
|
||||
return;
|
||||
}
|
||||
const auto& backendBufferObject = backendBufferIt->second;
|
||||
backendBufferObject->Bind(GL_PIXEL_PACK_BUFFER);
|
||||
MG_External::GLES::glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&prevPixelPackBuffer);
|
||||
} else {
|
||||
usePBO = false;
|
||||
MGLOG_D("GetTexImage: Not using PBO");
|
||||
}
|
||||
MGLOG_D("GetTexImage: glReadPixels()");
|
||||
MG_External::GLES::glReadPixels(0, 0, size.x(), size.y(), format, type, pixels);
|
||||
if (usePBO) {
|
||||
// pull back to client memory if PBO is used
|
||||
MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory");
|
||||
GLvoid* pboMappedPtr = MG_External::GLES::glMapBufferRange(
|
||||
GL_PIXEL_PACK_BUFFER, 0, pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT);
|
||||
if (pboMappedPtr) {
|
||||
MGLOG_D("ReadPixels: Copying data from PBO to client memory");
|
||||
SizeT size = pixelPackBufferObject->GetSize();
|
||||
pixelPackBufferObject->UploadSubData({pboMappedPtr, size}, 0);
|
||||
pixelPackBufferObject->ClearDirty();
|
||||
MGLOG_D("ReadPixels: Unmapping PBO");
|
||||
MG_External::GLES::glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
} else {
|
||||
MGLOG_E("ReadPixels: glMapBufferRange returned nullptr");
|
||||
MGLOG_E("ReadPixels: glMapBufferRange returned nullptr");
|
||||
}
|
||||
MGLOG_D("ReadPixels: Restoring previous pixel pack buffer binding %u", prevPixelPackBuffer);
|
||||
|
||||
MG_External::GLES::glBindBuffer(GL_PIXEL_PACK_BUFFER, prevPixelPackBuffer);
|
||||
}
|
||||
MGLOG_D("GetTexImage: finished");
|
||||
}
|
||||
|
||||
} // namespace MobileGL::MG_Backend::DirectGLES
|
||||
@@ -53,4 +53,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
GLsizei height);
|
||||
void GenerateMipmap(GLenum target);
|
||||
const GLubyte* GetString(GLenum name);
|
||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
|
||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
|
||||
|
||||
} // namespace MobileGL::MG_Backend::DirectGLES
|
||||
@@ -151,7 +151,7 @@ DECLARE_GL_FUNCTION_HEAD(void, LineWidth, GLfloat width) DECLARE_GL_FUNCTION_END
|
||||
DECLARE_GL_FUNCTION_HEAD(void, LinkProgram, GLuint program) DECLARE_GL_FUNCTION_END_NO_RETURN(void, LinkProgram, program)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, PixelStorei, GLenum pname, GLint param) DECLARE_GL_FUNCTION_END_NO_RETURN(void, PixelStorei, pname, param)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, PolygonOffset, GLfloat factor, GLfloat units) DECLARE_GL_FUNCTION_END_NO_RETURN(void, PolygonOffset, factor, units)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ReadPixels, x, y, width, height, format, type, pixels)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ReadPixels, x, y, width, height, format, type, pixels)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ReleaseShaderCompiler) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ReleaseShaderCompiler)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, RenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, RenderbufferStorage, target, internalformat, width, height)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, SampleCoverage, GLfloat value, GLboolean invert) DECLARE_GL_FUNCTION_END_NO_RETURN(void, SampleCoverage, value, invert)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "GL_Framebuffer.h"
|
||||
#include "Validators.h"
|
||||
#include "Config.h"
|
||||
#include <MG_Util/Metrics/TextureMetrics.h>
|
||||
#include <MG_Impl/GLImpl/Texture/Validators.h>
|
||||
#include <MG_State/GLState/ErrorState/Error.h>
|
||||
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
||||
@@ -310,10 +311,10 @@ namespace MobileGL {
|
||||
// ------------------- Check validity begin ------------------------
|
||||
if (attType == FramebufferAttachmentType::Unknown) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||
std::format("`mode` = {} is not an accepted value.",
|
||||
MG_Util::ConvertGLEnumToString(mode))));
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>(
|
||||
"MG_Impl/GLImpl", __func__,
|
||||
std::format("`mode` = {} is not an accepted value.", MG_Util::ConvertGLEnumToString(mode))));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -507,7 +508,142 @@ namespace MobileGL {
|
||||
#endif
|
||||
}
|
||||
|
||||
void ReadPixels_State(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
void* pixels) {
|
||||
TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format);
|
||||
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
||||
|
||||
// Check width/height
|
||||
if (width < 0 || height < 0) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"Width and height must be non-negative"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate format
|
||||
if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Invalid format"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate type
|
||||
if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Invalid pixel data type"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get bound framebuffer
|
||||
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read);
|
||||
auto framebufferObject = bindingSlot.GetBoundObject();
|
||||
|
||||
if (!framebufferObject) {
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"No framebuffer bound to read target"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check framebuffer completeness
|
||||
if (!framebufferObject->CheckCompleteness()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidFramebufferOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Framebuffer is incomplete"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for required buffers
|
||||
if (textureInputFormat == TextureInputFormat::StencilIndex) {
|
||||
if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"No stencil buffer for stencil index format"));
|
||||
return;
|
||||
}
|
||||
} else if (textureInputFormat == TextureInputFormat::DepthComponent) {
|
||||
if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"No depth buffer for depth component format"));
|
||||
return;
|
||||
}
|
||||
} else if (textureInputFormat == TextureInputFormat::DepthStencil) {
|
||||
if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid() ||
|
||||
!framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"No depth/stencil buffer for depth-stencil format"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate type for depth/stencil
|
||||
if (texturePixelDataType != TexturePixelDataType::UnsignedInt248 &&
|
||||
texturePixelDataType != TexturePixelDataType::Float32UnsignedInt248Rev) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"Invalid type for depth-stencil format"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check PBO state
|
||||
const auto& pixelPackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
|
||||
|
||||
if (pixelPackBufferObject) {
|
||||
// Check if PBO is mapped
|
||||
if (pixelPackBufferObject->IsMapped()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"Pixel pack buffer is currently mapped"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check alignment
|
||||
const SizeT typeSize = MG_Util::GetTexturePixelDataTypeSize(texturePixelDataType);
|
||||
if (reinterpret_cast<uintptr_t>(pixels) % typeSize != 0) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"Pixel data not aligned for pixel pack buffer"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check multisampling
|
||||
if (framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).IsRenderbuffer()) {
|
||||
auto rbo = framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).GetRenderbuffer();
|
||||
if (rbo && rbo->GetSamples() > 1) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
|
||||
"ReadPixels not supported for multisampled framebuffers"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadPixels_Backend(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
void* pixels) {
|
||||
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
|
||||
MG_Backend::DirectGLES::ReadPixels(x, y, width, height, format, type, pixels);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
|
||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
||||
ReadPixels_State(x, y, width, height, format, type, pixels);
|
||||
ReadPixels_Backend(x, y, width, height, format, type, pixels);
|
||||
}
|
||||
|
||||
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
|
||||
ClearBufferfi_Backend(buffer, drawbuffer, depth, stencil);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
namespace MobileGL {
|
||||
namespace MG_Impl::GLImpl {
|
||||
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
|
||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
|
||||
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
||||
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value);
|
||||
|
||||
@@ -1164,10 +1164,6 @@ namespace MobileGL {
|
||||
}
|
||||
}
|
||||
|
||||
void GetTexImage_State(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void GetCompressedTexImage_State(GLenum target, GLint level, void* img) {
|
||||
// TODO: implement
|
||||
}
|
||||
@@ -1378,7 +1374,136 @@ namespace MobileGL {
|
||||
MG_State::pGLContext->SetActiveTextureUnit(texture - GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void GetTexImage_Backend(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
|
||||
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
|
||||
MG_Backend::DirectGLES::GetTexImage(target, level, format, type, pixels);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add to GL_Texture.cpp
|
||||
void GetTexImage_State(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
|
||||
// ======================= Converting ================================
|
||||
TextureUploadTarget textureUploadTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
|
||||
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
||||
TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format);
|
||||
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
||||
|
||||
// ===================== Error Checking ==============================
|
||||
// Validate target
|
||||
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadTarget)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State", "Invalid texture target"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate level
|
||||
if (level < 0) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State", "Level must be non-negative"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate format
|
||||
if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State", "Invalid format"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate type
|
||||
if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State", "Invalid pixel data type"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get texture object
|
||||
SharedPtr<MG_State::GLState::ITextureObject> textureObject = nullptr;
|
||||
if (TextureImpl::IsProxyTextureTarget(textureUploadTarget)) {
|
||||
textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadTarget);
|
||||
} else {
|
||||
auto activeUnit =
|
||||
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
|
||||
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
|
||||
textureObject = bindingSlot.GetBoundObject();
|
||||
}
|
||||
|
||||
if (!TextureImpl::ValidateTextureObject(textureObject)) {
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State",
|
||||
"No valid texture bound to target"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check texture completeness
|
||||
if (!textureObject->IsComplete()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State", "Texture is incomplete"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check PBO state
|
||||
const auto& pixelPackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
|
||||
|
||||
if (pixelPackBufferObject) {
|
||||
// Check if PBO is mapped
|
||||
if (pixelPackBufferObject->IsMapped()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State",
|
||||
"Pixel pack buffer is currently mapped"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check alignment
|
||||
const SizeT typeSize = MG_Util::GetTexturePixelDataTypeSize(texturePixelDataType);
|
||||
if (reinterpret_cast<uintptr_t>(pixels) % typeSize != 0) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State",
|
||||
"Pixel data not aligned for pixel pack buffer"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Special case for depth/stencil
|
||||
if (textureInputFormat == TextureInputFormat::StencilIndex) {
|
||||
if (textureObject->GetFormat() != TextureInternalFormat::DepthStencil &&
|
||||
textureObject->GetFormat() != TextureInternalFormat::Depth24Stencil8 &&
|
||||
textureObject->GetFormat() != TextureInternalFormat::Depth32FStencil8) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State",
|
||||
"No stencil buffer for stencil index format"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for multisampling
|
||||
if (textureObject->GetStorageType() == TextureStorageType::Mipmap) {
|
||||
auto mipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
|
||||
if (mipmapObject->GetMipmapLevelCount() > 1) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexImage_State",
|
||||
"Multisampled textures not supported for GetTexImage"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
|
||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
|
||||
GetTexImage_State(target, level, format, type, pixels);
|
||||
GetTexImage_Backend(target, level, format, type, pixels);
|
||||
}
|
||||
|
||||
void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
|
||||
GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) {
|
||||
TexSubImage3D_State(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
|
||||
@@ -1475,10 +1600,6 @@ namespace MobileGL {
|
||||
GetTexLevelParameterfv_State(target, level, pname, params);
|
||||
}
|
||||
|
||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
|
||||
GetTexImage_State(target, level, format, type, pixels);
|
||||
}
|
||||
|
||||
void GetCompressedTexImage(GLenum target, GLint level, void* img) {
|
||||
GetCompressedTexImage_State(target, level, img);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace MobileGL {
|
||||
namespace MG_Impl::GLImpl {
|
||||
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
|
||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
|
||||
void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
|
||||
GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
|
||||
void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
@@ -43,7 +44,6 @@ namespace MobileGL {
|
||||
void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
|
||||
void GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params);
|
||||
void GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params);
|
||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
|
||||
void GetCompressedTexImage(GLenum target, GLint level, void* img);
|
||||
void GenTextures(GLsizei n, GLuint* textures);
|
||||
void DeleteTextures(GLsizei n, const GLuint* textures);
|
||||
|
||||
@@ -239,6 +239,12 @@ namespace MobileGL {
|
||||
}
|
||||
}
|
||||
|
||||
SizeT GetTexturePixelDataTypeSize(TexturePixelDataType type) {
|
||||
SizeT sizedPixelFormatSize = GetSizedTexturePixelDataTypeSize(type);
|
||||
if (sizedPixelFormatSize > 0) return sizedPixelFormatSize;
|
||||
return GetBaseTexturePixelDataTypeSize(type);
|
||||
}
|
||||
|
||||
SizeT GetInternalBytesPerPixel(TextureInternalFormat internalformat, TexturePixelDataType type) {
|
||||
SizeT sizedTextureFormatSize = GetSizedInternalFormatSizeInBytes(internalformat);
|
||||
if (sizedTextureFormatSize > 0) return sizedTextureFormatSize;
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace MobileGL {
|
||||
SizeT GetBaseInternalFormatComponentCount(TextureInternalFormat format);
|
||||
SizeT GetSizedTexturePixelDataTypeSize(TexturePixelDataType type);
|
||||
SizeT GetBaseTexturePixelDataTypeSize(TexturePixelDataType type);
|
||||
SizeT GetTexturePixelDataTypeSize(TexturePixelDataType type);
|
||||
// This should respect internal format more
|
||||
SizeT GetInternalBytesPerPixel(TextureInternalFormat internalformat, TexturePixelDataType type);
|
||||
// This should respect type more, representing data passed in
|
||||
|
||||
Reference in New Issue
Block a user