Bug 1285047 - Initialize all 3D texture data. - r=mtseng

MozReview-Commit-ID: 8ddc9yvV8tA
This commit is contained in:
Jeff Gilbert 2016-07-06 15:08:20 -07:00
Родитель bf05496a83
Коммит 9c70251dd9
1 изменённых файлов: 89 добавлений и 84 удалений

Просмотреть файл

@ -974,112 +974,117 @@ WebGLFramebuffer::ValidateAndInitAttachments(const char* funcName)
// Cool! We've checked out ok. Just need to initialize.
//////
// Check if we need to initialize anything
{
bool hasUninitializedAttachments = false;
if (mColorAttachment0.HasImage() && IsDrawBuffer(0))
hasUninitializedAttachments |= mColorAttachment0.HasUninitializedImageData();
std::vector<WebGLFBAttachPoint*> tex3DToClear;
size_t i = 1;
for (const auto& cur : mMoreColorAttachments) {
if (cur.HasImage() && IsDrawBuffer(i))
hasUninitializedAttachments |= cur.HasUninitializedImageData();
const auto fnGatherIf3D = [&](WebGLFBAttachPoint& attach) {
if (!attach.Texture())
return false;
++i;
}
const auto& info = attach.Texture()->ImageInfoAt(attach.ImageTarget(),
attach.MipLevel());
if (info.mDepth == 1)
return false;
if (mDepthAttachment.HasImage())
hasUninitializedAttachments |= mDepthAttachment.HasUninitializedImageData();
if (mStencilAttachment.HasImage())
hasUninitializedAttachments |= mStencilAttachment.HasUninitializedImageData();
if (mDepthStencilAttachment.HasImage())
hasUninitializedAttachments |= mDepthStencilAttachment.HasUninitializedImageData();
tex3DToClear.push_back(&attach);
return true;
};
if (!hasUninitializedAttachments)
return true;
}
//////
// Get buffer-bit-mask and color-attachment-mask-list
uint32_t clearBits = 0;
std::vector<GLenum> tempDrawBuffers(1 + mMoreColorAttachments.Size(), LOCAL_GL_NONE);
std::vector<GLenum> drawBuffersForClear(1 + mMoreColorAttachments.Size(),
LOCAL_GL_NONE);
std::vector<WebGLFBAttachPoint*> attachmentsToClear;
attachmentsToClear.reserve(1 + mMoreColorAttachments.Size() + 3);
const auto fnGatherColor = [&](WebGLFBAttachPoint& attach, uint32_t colorAttachNum) {
if (!IsDrawBuffer(colorAttachNum) || !attach.HasUninitializedImageData())
return;
if (fnGatherIf3D(attach))
return;
attachmentsToClear.push_back(&attach);
if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
tempDrawBuffers[0] = LOCAL_GL_COLOR_ATTACHMENT0;
drawBuffersForClear[colorAttachNum] = LOCAL_GL_COLOR_ATTACHMENT0 + colorAttachNum;
};
const auto fnGatherOther = [&](WebGLFBAttachPoint& attach, GLenum attachClearBits) {
if (!attach.HasUninitializedImageData())
return;
if (fnGatherIf3D(attach))
return;
attachmentsToClear.push_back(&attach);
clearBits |= attachClearBits;
};
//////
fnGatherColor(mColorAttachment0, 0);
size_t colorAttachNum = 1;
for (auto& cur : mMoreColorAttachments) {
fnGatherColor(cur, colorAttachNum);
++colorAttachNum;
}
size_t i = 1;
for (const auto& cur : mMoreColorAttachments) {
if (cur.HasUninitializedImageData() && IsDrawBuffer(i)) {
clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
tempDrawBuffers[i] = LOCAL_GL_COLOR_ATTACHMENT0 + i;
}
fnGatherOther(mDepthAttachment, LOCAL_GL_DEPTH_BUFFER_BIT);
fnGatherOther(mStencilAttachment, LOCAL_GL_STENCIL_BUFFER_BIT);
fnGatherOther(mDepthStencilAttachment,
LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
++i;
}
if (mDepthAttachment.HasUninitializedImageData() ||
mDepthStencilAttachment.HasUninitializedImageData())
{
clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT;
}
if (mStencilAttachment.HasUninitializedImageData() ||
mDepthStencilAttachment.HasUninitializedImageData())
{
clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT;
}
//////
mContext->MakeContextCurrent();
const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) {
const GLenum* ptr = nullptr;
if (list.size()) {
ptr = &(list[0]);
if (clearBits) {
const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) {
this->mContext->gl->fDrawBuffers(list.size(), list.data());
};
const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers;
const bool hasDrawBuffers = (mContext->IsWebGL2() ||
mContext->IsExtensionEnabled(drawBufferExt));
if (hasDrawBuffers) {
fnDrawBuffers(drawBuffersForClear);
}
this->mContext->gl->fDrawBuffers(list.size(), ptr);
};
const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers;
const bool hasDrawBuffers = (mContext->IsWebGL2() ||
mContext->IsExtensionEnabled(drawBufferExt));
////////////
if (hasDrawBuffers) {
fnDrawBuffers(tempDrawBuffers);
// Clear!
{
gl::ScopedBindFramebuffer autoBind(mContext->gl, mGLName);
mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);
}
if (hasDrawBuffers) {
fnDrawBuffers(mDrawBuffers);
}
for (auto* cur : attachmentsToClear) {
cur->SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
}
}
// Clear!
{
// This FB maybe bind to GL_READ_FRAMEBUFFER and glClear only
// clear GL_DRAW_FRAMEBUFFER. So bind FB to GL_DRAW_FRAMEBUFFER
// here.
gl::ScopedBindFramebuffer autoFB(mContext->gl, mGLName);
mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);
}
//////
if (hasDrawBuffers) {
fnDrawBuffers(mDrawBuffers);
}
// Mark all the uninitialized images as initialized.
if (mDepthAttachment.HasUninitializedImageData())
mDepthAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
if (mStencilAttachment.HasUninitializedImageData())
mStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
if (mDepthStencilAttachment.HasUninitializedImageData())
mDepthStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
mColorAttachment0.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
}
i = 1;
for (auto& cur : mMoreColorAttachments) {
if (cur.HasUninitializedImageData() && IsDrawBuffer(i))
cur.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
++i;
for (auto* attach : tex3DToClear) {
auto* tex = attach->Texture();
if (!tex->InitializeImageData(funcName, attach->ImageTarget(),
attach->MipLevel()))
{
return false;
}
}
return true;