2012-10-05 00:35:54 +04:00
|
|
|
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
2012-12-09 15:58:41 +04:00
|
|
|
|
#include "WebGLFramebuffer.h"
|
2014-07-15 03:55:33 +04:00
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
|
#include "GLContext.h"
|
|
|
|
|
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
2015-12-15 03:11:59 +03:00
|
|
|
|
#include "nsPrintfCString.h"
|
2014-07-15 03:55:33 +04:00
|
|
|
|
#include "WebGLContext.h"
|
|
|
|
|
#include "WebGLContextUtils.h"
|
2013-06-22 03:44:17 +04:00
|
|
|
|
#include "WebGLExtensions.h"
|
2013-06-11 00:00:35 +04:00
|
|
|
|
#include "WebGLRenderbuffer.h"
|
2013-06-22 03:44:17 +04:00
|
|
|
|
#include "WebGLTexture.h"
|
2014-07-15 03:55:33 +04:00
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
|
namespace mozilla {
|
2012-10-05 00:35:54 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFBAttachPoint::WebGLFBAttachPoint(WebGLFramebuffer* fb, GLenum attachmentPoint)
|
2015-03-25 02:00:28 +03:00
|
|
|
|
: mFB(fb)
|
|
|
|
|
, mAttachmentPoint(attachmentPoint)
|
2014-09-19 03:14:22 +04:00
|
|
|
|
, mTexImageTarget(LOCAL_GL_NONE)
|
2015-03-25 02:00:28 +03:00
|
|
|
|
{ }
|
2014-07-30 23:52:07 +04:00
|
|
|
|
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFBAttachPoint::~WebGLFBAttachPoint()
|
2014-07-30 23:52:07 +04:00
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
MOZ_ASSERT(!mRenderbufferPtr);
|
|
|
|
|
MOZ_ASSERT(!mTexturePtr);
|
2014-07-30 23:52:07 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
void
|
|
|
|
|
WebGLFBAttachPoint::Unlink()
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-09 15:58:41 +04:00
|
|
|
|
bool
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFBAttachPoint::IsDeleteRequested() const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2012-12-09 15:58:41 +04:00
|
|
|
|
return Texture() ? Texture()->IsDeleteRequested()
|
|
|
|
|
: Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
|
|
|
|
|
: false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-23 21:48:27 +04:00
|
|
|
|
bool
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFBAttachPoint::IsDefined() const
|
2014-09-23 21:48:27 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
/*
|
|
|
|
|
return (Renderbuffer() && Renderbuffer()->IsDefined()) ||
|
|
|
|
|
(Texture() && Texture()->ImageInfoAt(mTexImageTarget,
|
|
|
|
|
mTexImageLevel).IsDefined());
|
|
|
|
|
*/
|
|
|
|
|
return (Renderbuffer() || Texture());
|
2014-09-23 21:48:27 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const webgl::FormatUsageInfo*
|
|
|
|
|
WebGLFBAttachPoint::Format() const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(IsDefined());
|
2014-02-14 03:07:59 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (Texture())
|
|
|
|
|
return Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).mFormat;
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
|
|
|
|
if (Renderbuffer())
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return Renderbuffer()->Format();
|
2015-11-24 06:27:13 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
WebGLFBAttachPoint::HasAlpha() const
|
|
|
|
|
{
|
|
|
|
|
return Format()->format->hasAlpha;
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const webgl::FormatUsageInfo*
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFramebuffer::GetFormatForAttachment(const WebGLFBAttachPoint& attachment) const
|
2014-08-21 00:38:42 +04:00
|
|
|
|
{
|
|
|
|
|
MOZ_ASSERT(attachment.IsDefined());
|
|
|
|
|
MOZ_ASSERT(attachment.Texture() || attachment.Renderbuffer());
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return attachment.Format();
|
2014-08-21 00:38:42 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
bool
|
|
|
|
|
WebGLFBAttachPoint::IsReadableFloat() const
|
2014-03-08 01:26:17 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
auto formatUsage = Format();
|
|
|
|
|
MOZ_ASSERT(formatUsage);
|
2014-03-08 01:26:17 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
auto format = formatUsage->format;
|
|
|
|
|
if (!format->isColorFormat)
|
|
|
|
|
return false;
|
2014-03-08 01:26:17 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return format->componentType == webgl::ComponentType::Float;
|
2014-10-08 03:52:58 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
void
|
|
|
|
|
WebGLFBAttachPoint::Clear()
|
2014-10-08 03:52:58 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mRenderbufferPtr) {
|
|
|
|
|
MOZ_ASSERT(!mTexturePtr);
|
|
|
|
|
mRenderbufferPtr->UnmarkAttachment(*this);
|
|
|
|
|
} else if (mTexturePtr) {
|
|
|
|
|
mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel).RemoveAttachPoint(this);
|
|
|
|
|
}
|
2014-03-08 01:26:17 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
mTexturePtr = nullptr;
|
|
|
|
|
mRenderbufferPtr = nullptr;
|
2015-03-25 02:00:28 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
OnBackingStoreRespecified();
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-09 15:58:41 +04:00
|
|
|
|
void
|
2015-07-03 04:55:43 +03:00
|
|
|
|
WebGLFBAttachPoint::SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level)
|
|
|
|
|
{
|
|
|
|
|
SetTexImageLayer(tex, target, level, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
WebGLFBAttachPoint::SetTexImageLayer(WebGLTexture* tex, TexImageTarget target,
|
|
|
|
|
GLint level, GLint layer)
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
Clear();
|
2015-03-25 02:00:28 +03:00
|
|
|
|
|
2012-12-09 15:58:41 +04:00
|
|
|
|
mTexturePtr = tex;
|
2013-10-02 04:30:38 +04:00
|
|
|
|
mTexImageTarget = target;
|
|
|
|
|
mTexImageLevel = level;
|
2015-07-03 04:55:43 +03:00
|
|
|
|
mTexImageLayer = layer;
|
2014-03-12 03:10:59 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mTexturePtr) {
|
|
|
|
|
mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel).AddAttachPoint(this);
|
|
|
|
|
}
|
2014-03-12 03:10:59 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFBAttachPoint::SetRenderbuffer(WebGLRenderbuffer* rb)
|
2014-03-12 03:10:59 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
Clear();
|
2015-03-25 02:00:28 +03:00
|
|
|
|
|
2014-03-12 03:10:59 +04:00
|
|
|
|
mRenderbufferPtr = rb;
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mRenderbufferPtr) {
|
|
|
|
|
mRenderbufferPtr->MarkAttachment(*this);
|
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFBAttachPoint::HasUninitializedImageData() const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
|
|
|
|
if (!HasImage())
|
2013-10-11 17:16:43 +04:00
|
|
|
|
return false;
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mRenderbufferPtr)
|
|
|
|
|
return mRenderbufferPtr->HasUninitializedImageData();
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(mTexturePtr);
|
2015-11-24 06:27:13 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
auto& imageInfo = mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel);
|
|
|
|
|
MOZ_ASSERT(imageInfo.IsDefined());
|
|
|
|
|
|
|
|
|
|
return !imageInfo.IsDataInitialized();
|
2013-10-11 17:16:43 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFBAttachPoint::SetImageDataStatus(WebGLImageDataStatus newStatus)
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
|
|
|
|
if (!HasImage())
|
|
|
|
|
return;
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mRenderbufferPtr) {
|
|
|
|
|
mRenderbufferPtr->mImageDataStatus = newStatus;
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return;
|
2014-02-14 03:07:59 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(mTexturePtr);
|
|
|
|
|
|
|
|
|
|
auto& imageInfo = mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel);
|
|
|
|
|
MOZ_ASSERT(imageInfo.IsDefined());
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const bool isDataInitialized = (newStatus == WebGLImageDataStatus::InitializedImageData);
|
|
|
|
|
imageInfo.SetIsDataInitialized(isDataInitialized, mTexturePtr);
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
bool
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFBAttachPoint::HasImage() const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (Texture() && Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).IsDefined())
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return true;
|
2014-02-14 03:07:59 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (Renderbuffer() && Renderbuffer()->IsDefined())
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
void
|
|
|
|
|
WebGLFBAttachPoint::Size(uint32_t* const out_width, uint32_t* const out_height) const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(HasImage());
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (Renderbuffer()) {
|
|
|
|
|
*out_width = Renderbuffer()->Width();
|
|
|
|
|
*out_height = Renderbuffer()->Height();
|
|
|
|
|
return;
|
2014-02-14 03:07:59 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(Texture());
|
|
|
|
|
MOZ_ASSERT(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).IsDefined());
|
|
|
|
|
const auto& imageInfo = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
|
2015-11-24 08:55:59 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
*out_width = imageInfo.mWidth;
|
|
|
|
|
*out_height = imageInfo.mHeight;
|
2015-11-24 08:55:59 +03:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
void
|
|
|
|
|
WebGLFBAttachPoint::OnBackingStoreRespecified() const
|
2015-11-24 08:55:59 +03:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
mFB->InvalidateFramebufferStatus();
|
2013-11-05 01:05:04 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
void
|
|
|
|
|
WebGLFBAttachPoint::AttachmentName(nsCString* out) const
|
|
|
|
|
{
|
|
|
|
|
switch (mAttachmentPoint) {
|
|
|
|
|
case LOCAL_GL_DEPTH_ATTACHMENT:
|
|
|
|
|
out->AssignLiteral("DEPTH_ATTACHMENT");
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_STENCIL_ATTACHMENT:
|
|
|
|
|
out->AssignLiteral("STENCIL_ATTACHMENT");
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
|
|
|
|
|
out->AssignLiteral("DEPTH_STENCIL_ATTACHMENT");
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
MOZ_ASSERT(mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0);
|
|
|
|
|
out->AssignLiteral("COLOR_ATTACHMENT");
|
|
|
|
|
const uint32_t n = mAttachmentPoint - LOCAL_GL_COLOR_ATTACHMENT0;
|
|
|
|
|
out->AppendInt(n);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-22 02:04:08 +03:00
|
|
|
|
bool
|
2015-12-15 03:11:59 +03:00
|
|
|
|
WebGLFBAttachPoint::IsComplete(WebGLContext* webgl, nsCString* const out_info) const
|
2014-11-22 02:04:08 +03:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(IsDefined());
|
2014-11-22 02:04:08 +03:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
if (!HasImage()) {
|
|
|
|
|
AttachmentName(out_info);
|
|
|
|
|
out_info->AppendLiteral("'s image is not defined");
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return false;
|
2015-12-15 03:11:59 +03:00
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
uint32_t width;
|
|
|
|
|
uint32_t height;
|
|
|
|
|
Size(&width, &height);
|
2015-12-15 03:11:59 +03:00
|
|
|
|
if (!width || !height) {
|
|
|
|
|
AttachmentName(out_info);
|
|
|
|
|
out_info->AppendLiteral(" has no width or height");
|
2015-11-24 06:27:13 +03:00
|
|
|
|
return false;
|
2015-12-15 03:11:59 +03:00
|
|
|
|
}
|
2015-11-24 08:55:59 +03:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
const auto formatUsage = Format();
|
|
|
|
|
if (!formatUsage->isRenderable) {
|
|
|
|
|
nsAutoCString attachName;
|
|
|
|
|
AttachmentName(&attachName);
|
|
|
|
|
|
|
|
|
|
*out_info = nsPrintfCString("%s has an effective format of %s, which is not"
|
|
|
|
|
" renderable",
|
|
|
|
|
attachName.BeginReading(), formatUsage->format->name);
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return false;
|
2015-12-15 03:11:59 +03:00
|
|
|
|
}
|
2014-01-24 07:53:53 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
const auto format = formatUsage->format;
|
|
|
|
|
|
|
|
|
|
bool hasRequiredBits;
|
2014-01-24 07:53:53 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
switch (mAttachmentPoint) {
|
|
|
|
|
case LOCAL_GL_DEPTH_ATTACHMENT:
|
|
|
|
|
hasRequiredBits = format->hasDepth;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_STENCIL_ATTACHMENT:
|
|
|
|
|
hasRequiredBits = format->hasStencil;
|
|
|
|
|
break;
|
2014-08-20 00:24:39 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
|
|
|
|
|
MOZ_ASSERT(!webgl->IsWebGL2());
|
|
|
|
|
hasRequiredBits = (format->hasDepth && format->hasStencil);
|
|
|
|
|
break;
|
2014-01-24 07:53:53 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
default:
|
|
|
|
|
MOZ_ASSERT(mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0);
|
|
|
|
|
hasRequiredBits = format->isColorFormat;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2014-01-24 07:53:53 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
if (!hasRequiredBits) {
|
|
|
|
|
AttachmentName(out_info);
|
|
|
|
|
out_info->AppendLiteral("'s format is missing required color/depth/stencil bits");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!webgl->IsWebGL2()) {
|
|
|
|
|
bool hasSurplusPlanes = false;
|
|
|
|
|
|
|
|
|
|
switch (mAttachmentPoint) {
|
|
|
|
|
case LOCAL_GL_DEPTH_ATTACHMENT:
|
|
|
|
|
hasSurplusPlanes = format->hasStencil;
|
|
|
|
|
break;
|
2014-01-24 07:53:53 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
case LOCAL_GL_STENCIL_ATTACHMENT:
|
|
|
|
|
hasSurplusPlanes = format->hasDepth;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hasSurplusPlanes) {
|
|
|
|
|
AttachmentName(out_info);
|
|
|
|
|
out_info->AppendLiteral("'s format has depth or stencil bits when it"
|
|
|
|
|
" shouldn't");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2015-11-24 08:55:59 +03:00
|
|
|
|
}
|
2015-11-25 07:15:29 +03:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
return true;
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-02 04:30:05 +04:00
|
|
|
|
void
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFBAttachPoint::FinalizeAttachment(gl::GLContext* gl, GLenum attachment) const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2014-03-12 03:10:59 +04:00
|
|
|
|
if (!HasImage()) {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
switch (attachment) {
|
2015-03-25 02:00:28 +03:00
|
|
|
|
case LOCAL_GL_DEPTH_ATTACHMENT:
|
|
|
|
|
case LOCAL_GL_STENCIL_ATTACHMENT:
|
|
|
|
|
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment,
|
2014-03-12 03:10:59 +04:00
|
|
|
|
LOCAL_GL_RENDERBUFFER, 0);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
break;
|
2014-03-12 03:10:59 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-01-23 07:59:34 +04:00
|
|
|
|
MOZ_ASSERT(HasImage());
|
|
|
|
|
|
2013-10-02 04:30:05 +04:00
|
|
|
|
if (Texture()) {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(gl == Texture()->mContext->GL());
|
2014-03-12 03:10:59 +04:00
|
|
|
|
|
2014-09-19 03:14:22 +04:00
|
|
|
|
const GLenum imageTarget = ImageTarget().get();
|
|
|
|
|
const GLint mipLevel = MipLevel();
|
2015-07-03 04:55:43 +03:00
|
|
|
|
const GLint layer = Layer();
|
2015-05-21 02:55:34 +03:00
|
|
|
|
const GLuint glName = Texture()->mGLName;
|
2014-09-19 03:14:22 +04:00
|
|
|
|
|
2015-07-03 04:55:43 +03:00
|
|
|
|
switch (imageTarget) {
|
|
|
|
|
case LOCAL_GL_TEXTURE_2D:
|
|
|
|
|
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
|
|
|
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
|
|
|
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
|
|
|
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
|
|
|
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
|
|
|
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
2015-07-03 04:55:43 +03:00
|
|
|
|
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
|
|
|
|
|
imageTarget, glName, mipLevel);
|
2015-11-25 07:15:29 +03:00
|
|
|
|
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
|
|
|
|
|
LOCAL_GL_STENCIL_ATTACHMENT, imageTarget,
|
|
|
|
|
glName, mipLevel);
|
2015-07-03 04:55:43 +03:00
|
|
|
|
} else {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachment, imageTarget,
|
|
|
|
|
glName, mipLevel);
|
2015-07-03 04:55:43 +03:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_TEXTURE_2D_ARRAY:
|
|
|
|
|
case LOCAL_GL_TEXTURE_3D:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
2015-07-03 04:55:43 +03:00
|
|
|
|
gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER,
|
2015-11-25 07:15:29 +03:00
|
|
|
|
LOCAL_GL_DEPTH_ATTACHMENT, glName, mipLevel,
|
|
|
|
|
layer);
|
2015-07-03 04:55:43 +03:00
|
|
|
|
gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER,
|
2015-11-25 07:15:29 +03:00
|
|
|
|
LOCAL_GL_STENCIL_ATTACHMENT, glName,
|
|
|
|
|
mipLevel, layer);
|
2015-07-03 04:55:43 +03:00
|
|
|
|
} else {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER, attachment, glName,
|
|
|
|
|
mipLevel, layer);
|
2015-07-03 04:55:43 +03:00
|
|
|
|
}
|
|
|
|
|
break;
|
2013-10-02 04:31:09 +04:00
|
|
|
|
}
|
2015-07-03 04:55:43 +03:00
|
|
|
|
return ;
|
2013-10-02 04:30:05 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Renderbuffer()) {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
Renderbuffer()->FramebufferRenderbuffer(attachment);
|
2013-10-02 04:30:05 +04:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
MOZ_CRASH();
|
2013-10-02 04:30:05 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-06 09:31:00 +03:00
|
|
|
|
JS::Value
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFBAttachPoint::GetParameter(const char* funcName, WebGLContext* webgl, JSContext* cx,
|
|
|
|
|
GLenum target, GLenum attachment, GLenum pname,
|
|
|
|
|
ErrorResult* const out_error)
|
2015-08-06 09:31:00 +03:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const bool hasAttachment = (mTexturePtr || mRenderbufferPtr);
|
|
|
|
|
if (!hasAttachment) {
|
|
|
|
|
// Divergent between GLES 3 and 2.
|
|
|
|
|
|
|
|
|
|
// GLES 2.0.25 p127:
|
|
|
|
|
// "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, then querying any
|
|
|
|
|
// other pname will generate INVALID_ENUM."
|
|
|
|
|
|
|
|
|
|
// GLES 3.0.4 p240:
|
|
|
|
|
// "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, no framebuffer is
|
|
|
|
|
// bound to target. In this case querying pname
|
|
|
|
|
// FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero, and all other queries
|
|
|
|
|
// will generate an INVALID_OPERATION error."
|
|
|
|
|
switch (pname) {
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
|
|
|
|
|
return JS::Int32Value(LOCAL_GL_NONE);
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
|
|
|
|
|
if (webgl->IsWebGL2())
|
|
|
|
|
return JS::NullValue();
|
|
|
|
|
|
|
|
|
|
break;
|
2015-08-06 09:31:00 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-08-06 09:31:00 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (webgl->IsWebGL2()) {
|
|
|
|
|
webgl->ErrorInvalidOperation("%s: No attachment at %s.", funcName,
|
|
|
|
|
webgl->EnumName(attachment));
|
|
|
|
|
} else {
|
|
|
|
|
webgl->ErrorInvalidEnum("%s: No attachment at %s.", funcName,
|
|
|
|
|
webgl->EnumName(attachment));
|
|
|
|
|
}
|
|
|
|
|
return JS::NullValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isPNameValid = false;
|
2015-08-06 09:31:00 +03:00
|
|
|
|
switch (pname) {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
|
|
|
|
|
return JS::Int32Value(mTexturePtr ? LOCAL_GL_TEXTURE
|
|
|
|
|
: LOCAL_GL_RENDERBUFFER);
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
|
|
|
|
|
return (mTexturePtr ? webgl->WebGLObjectAsJSValue(cx, mTexturePtr.get(),
|
|
|
|
|
*out_error)
|
|
|
|
|
: webgl->WebGLObjectAsJSValue(cx, mRenderbufferPtr.get(),
|
|
|
|
|
*out_error));
|
|
|
|
|
////////////////
|
|
|
|
|
|
2015-08-06 09:31:00 +03:00
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
isPNameValid = true;
|
|
|
|
|
break;
|
2015-08-06 09:31:00 +03:00
|
|
|
|
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
|
|
|
|
|
isPNameValid = true;
|
|
|
|
|
break;
|
2015-08-06 09:31:00 +03:00
|
|
|
|
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (webgl->IsWebGL2() ||
|
|
|
|
|
webgl->IsExtensionEnabled(WebGLExtensionID::EXT_sRGB))
|
|
|
|
|
{
|
|
|
|
|
const auto format = Format()->format;
|
|
|
|
|
return JS::Int32Value(format->isSRGB ? LOCAL_GL_SRGB
|
|
|
|
|
: LOCAL_GL_LINEAR);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
////////////////
|
2015-08-06 09:31:00 +03:00
|
|
|
|
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mTexturePtr)
|
2015-08-06 09:31:00 +03:00
|
|
|
|
return JS::Int32Value(MipLevel());
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mTexturePtr) {
|
|
|
|
|
GLenum face = 0;
|
|
|
|
|
if (mTexturePtr->Target() == LOCAL_GL_TEXTURE_CUBE_MAP) {
|
2015-08-06 09:31:00 +03:00
|
|
|
|
face = ImageTarget().get();
|
|
|
|
|
}
|
|
|
|
|
return JS::Int32Value(face);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mTexturePtr) {
|
2015-08-06 09:31:00 +03:00
|
|
|
|
int32_t layer = 0;
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (ImageTarget() == LOCAL_GL_TEXTURE_2D_ARRAY ||
|
|
|
|
|
ImageTarget() == LOCAL_GL_TEXTURE_3D)
|
2015-08-06 09:31:00 +03:00
|
|
|
|
{
|
|
|
|
|
layer = Layer();
|
|
|
|
|
}
|
|
|
|
|
return JS::Int32Value(layer);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (!isPNameValid) {
|
|
|
|
|
webgl->ErrorInvalidEnum("%s: Invalid pname: 0x%04x", funcName, pname);
|
|
|
|
|
return JS::NullValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gl::GLContext* gl = webgl->GL();
|
|
|
|
|
gl->MakeCurrent();
|
|
|
|
|
|
|
|
|
|
GLint ret = 0;
|
|
|
|
|
gl->fGetFramebufferAttachmentParameteriv(target, attachment, pname, &ret);
|
|
|
|
|
return JS::Int32Value(ret);
|
2015-08-06 09:31:00 +03:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// WebGLFramebuffer
|
2015-03-17 07:32:52 +03:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
|
2015-05-21 02:50:28 +03:00
|
|
|
|
: WebGLContextBoundObject(webgl)
|
|
|
|
|
, mGLName(fbo)
|
2015-11-25 07:15:29 +03:00
|
|
|
|
, mIsKnownFBComplete(false)
|
2015-03-25 02:00:28 +03:00
|
|
|
|
, mReadBufferMode(LOCAL_GL_COLOR_ATTACHMENT0)
|
|
|
|
|
, mColorAttachment0(this, LOCAL_GL_COLOR_ATTACHMENT0)
|
|
|
|
|
, mDepthAttachment(this, LOCAL_GL_DEPTH_ATTACHMENT)
|
|
|
|
|
, mStencilAttachment(this, LOCAL_GL_STENCIL_ATTACHMENT)
|
|
|
|
|
, mDepthStencilAttachment(this, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
|
2015-11-25 07:15:29 +03:00
|
|
|
|
, mMoreColorAttachments(webgl->mGLMaxColorAttachments)
|
|
|
|
|
, mDrawBuffers(1, LOCAL_GL_COLOR_ATTACHMENT0)
|
2015-05-21 02:50:28 +03:00
|
|
|
|
#ifdef ANDROID
|
|
|
|
|
, mIsFB(false)
|
|
|
|
|
#endif
|
2015-03-17 04:03:40 +03:00
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
mContext->mFramebuffers.insertBack(this);
|
2015-03-17 07:32:52 +03:00
|
|
|
|
}
|
2015-03-17 04:22:17 +03:00
|
|
|
|
|
2015-03-17 07:32:52 +03:00
|
|
|
|
void
|
2015-03-25 02:00:28 +03:00
|
|
|
|
WebGLFramebuffer::Delete()
|
2015-03-17 07:32:52 +03:00
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
mColorAttachment0.Clear();
|
|
|
|
|
mDepthAttachment.Clear();
|
|
|
|
|
mStencilAttachment.Clear();
|
|
|
|
|
mDepthStencilAttachment.Clear();
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
for (auto& cur : mMoreColorAttachments) {
|
|
|
|
|
cur.Clear();
|
2014-06-24 11:15:44 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
mContext->MakeContextCurrent();
|
|
|
|
|
mContext->gl->fDeleteFramebuffers(1, &mGLName);
|
2015-11-25 07:15:29 +03:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
|
2015-05-21 02:50:28 +03:00
|
|
|
|
|
|
|
|
|
#ifdef ANDROID
|
|
|
|
|
mIsFB = false;
|
|
|
|
|
#endif
|
2014-06-24 11:15:44 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-09 15:58:41 +04:00
|
|
|
|
void
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFramebuffer::FramebufferRenderbuffer(GLenum attachment, RBTarget rbtarget,
|
2014-11-14 07:03:50 +03:00
|
|
|
|
WebGLRenderbuffer* rb)
|
2012-12-09 15:58:41 +04:00
|
|
|
|
{
|
2015-01-13 02:05:21 +03:00
|
|
|
|
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
|
|
|
|
|
mContext->mBoundReadFramebuffer == this);
|
2014-03-04 11:14:35 +04:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer", rb))
|
2012-12-09 15:58:41 +04:00
|
|
|
|
return;
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
// `attachPointEnum` is validated by ValidateFramebufferAttachment().
|
|
|
|
|
|
|
|
|
|
RefPtr<WebGLRenderbuffer> rb_ = rb; // Bug 1201275
|
|
|
|
|
const auto fnAttach = [this, &rb_](GLenum attachment) {
|
|
|
|
|
const auto attachPoint = this->GetAttachPoint(attachment);
|
|
|
|
|
MOZ_ASSERT(attachPoint);
|
|
|
|
|
|
|
|
|
|
attachPoint->SetRenderbuffer(rb_);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (mContext->IsWebGL2() && attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
|
|
|
|
fnAttach(LOCAL_GL_DEPTH_ATTACHMENT);
|
|
|
|
|
fnAttach(LOCAL_GL_STENCIL_ATTACHMENT);
|
|
|
|
|
} else {
|
|
|
|
|
fnAttach(attachment);
|
|
|
|
|
}
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
InvalidateFramebufferStatus();
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFramebuffer::FramebufferTexture2D(GLenum attachment, TexImageTarget texImageTarget,
|
2014-11-14 07:03:50 +03:00
|
|
|
|
WebGLTexture* tex, GLint level)
|
2012-12-09 15:58:41 +04:00
|
|
|
|
{
|
2015-01-13 02:05:21 +03:00
|
|
|
|
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
|
|
|
|
|
mContext->mBoundReadFramebuffer == this);
|
2014-03-04 11:14:35 +04:00
|
|
|
|
|
2015-02-18 02:52:51 +03:00
|
|
|
|
if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture", tex))
|
2012-12-09 15:58:41 +04:00
|
|
|
|
return;
|
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
|
if (tex) {
|
|
|
|
|
bool isTexture2D = tex->Target() == LOCAL_GL_TEXTURE_2D;
|
2014-09-19 03:14:22 +04:00
|
|
|
|
bool isTexTarget2D = texImageTarget == LOCAL_GL_TEXTURE_2D;
|
2013-10-31 21:01:41 +04:00
|
|
|
|
if (isTexture2D != isTexTarget2D) {
|
2014-11-14 07:03:50 +03:00
|
|
|
|
mContext->ErrorInvalidOperation("framebufferTexture2D: Mismatched"
|
|
|
|
|
" texture and texture target.");
|
|
|
|
|
return;
|
2013-10-31 21:01:41 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
RefPtr<WebGLTexture> tex_ = tex; // Bug 1201275
|
|
|
|
|
const auto fnAttach = [this, &tex_, texImageTarget, level](GLenum attachment) {
|
|
|
|
|
const auto attachPoint = this->GetAttachPoint(attachment);
|
|
|
|
|
MOZ_ASSERT(attachPoint);
|
|
|
|
|
|
|
|
|
|
attachPoint->SetTexImage(tex_, texImageTarget, level);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (mContext->IsWebGL2() && attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
|
|
|
|
fnAttach(LOCAL_GL_DEPTH_ATTACHMENT);
|
|
|
|
|
fnAttach(LOCAL_GL_STENCIL_ATTACHMENT);
|
|
|
|
|
} else {
|
|
|
|
|
fnAttach(attachment);
|
|
|
|
|
}
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
InvalidateFramebufferStatus();
|
2014-03-04 11:14:35 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-03 04:55:43 +03:00
|
|
|
|
void
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFramebuffer::FramebufferTextureLayer(GLenum attachment, WebGLTexture* tex,
|
2015-07-03 04:55:43 +03:00
|
|
|
|
GLint level, GLint layer)
|
|
|
|
|
{
|
|
|
|
|
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
|
|
|
|
|
mContext->mBoundReadFramebuffer == this);
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const TexImageTarget texImageTarget = (tex ? tex->Target().get()
|
|
|
|
|
: LOCAL_GL_TEXTURE_2D);
|
|
|
|
|
|
|
|
|
|
RefPtr<WebGLTexture> tex_ = tex; // Bug 1201275
|
|
|
|
|
const auto fnAttach = [this, &tex_, texImageTarget, level, layer](GLenum attachment) {
|
|
|
|
|
const auto attachPoint = this->GetAttachPoint(attachment);
|
|
|
|
|
MOZ_ASSERT(attachPoint);
|
|
|
|
|
|
|
|
|
|
attachPoint->SetTexImageLayer(tex_, texImageTarget, level, layer);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (mContext->IsWebGL2() && attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
|
|
|
|
fnAttach(LOCAL_GL_DEPTH_ATTACHMENT);
|
|
|
|
|
fnAttach(LOCAL_GL_STENCIL_ATTACHMENT);
|
|
|
|
|
} else {
|
|
|
|
|
fnAttach(attachment);
|
|
|
|
|
}
|
2015-07-03 04:55:43 +03:00
|
|
|
|
|
|
|
|
|
InvalidateFramebufferStatus();
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFBAttachPoint*
|
|
|
|
|
WebGLFramebuffer::GetAttachPoint(GLenum attachPoint)
|
2014-03-04 11:14:35 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
switch (attachPoint) {
|
2015-03-25 02:00:28 +03:00
|
|
|
|
case LOCAL_GL_COLOR_ATTACHMENT0:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return &mColorAttachment0;
|
2015-03-17 07:32:52 +03:00
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
|
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return &mDepthStencilAttachment;
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
|
|
|
|
case LOCAL_GL_DEPTH_ATTACHMENT:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return &mDepthAttachment;
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
|
|
|
|
case LOCAL_GL_STENCIL_ATTACHMENT:
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return &mStencilAttachment;
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const auto lastCAEnum = mContext->LastColorAttachmentEnum();
|
|
|
|
|
if (attachPoint < LOCAL_GL_COLOR_ATTACHMENT1 ||
|
|
|
|
|
attachPoint > lastCAEnum)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mMoreColorAttachments.Size()) {
|
|
|
|
|
for (GLenum cur = LOCAL_GL_COLOR_ATTACHMENT1; cur <= lastCAEnum; cur++) {
|
|
|
|
|
mMoreColorAttachments.AppendNew(this, cur);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
2013-06-22 03:44:17 +04:00
|
|
|
|
}
|
2015-11-25 07:15:29 +03:00
|
|
|
|
MOZ_ASSERT(LOCAL_GL_COLOR_ATTACHMENT0 + mMoreColorAttachments.Size() == lastCAEnum);
|
2013-06-22 03:44:17 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const size_t offset = attachPoint - LOCAL_GL_COLOR_ATTACHMENT1;
|
|
|
|
|
MOZ_ASSERT(offset <= mMoreColorAttachments.Size());
|
|
|
|
|
return &mMoreColorAttachments[offset];
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2014-01-23 07:59:34 +04:00
|
|
|
|
WebGLFramebuffer::DetachTexture(const WebGLTexture* tex)
|
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
if (mColorAttachment0.Texture() == tex)
|
|
|
|
|
mColorAttachment0.Clear();
|
2015-03-17 04:22:17 +03:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
if (mDepthAttachment.Texture() == tex)
|
|
|
|
|
mDepthAttachment.Clear();
|
|
|
|
|
|
|
|
|
|
if (mStencilAttachment.Texture() == tex)
|
|
|
|
|
mStencilAttachment.Clear();
|
|
|
|
|
|
|
|
|
|
if (mDepthStencilAttachment.Texture() == tex)
|
|
|
|
|
mDepthStencilAttachment.Clear();
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
for (auto& cur : mMoreColorAttachments) {
|
|
|
|
|
if (cur.Texture() == tex)
|
|
|
|
|
cur.Clear();
|
2014-11-14 07:03:50 +03:00
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2014-01-23 07:59:34 +04:00
|
|
|
|
WebGLFramebuffer::DetachRenderbuffer(const WebGLRenderbuffer* rb)
|
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
if (mColorAttachment0.Renderbuffer() == rb)
|
|
|
|
|
mColorAttachment0.Clear();
|
2015-03-17 04:22:17 +03:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
if (mDepthAttachment.Renderbuffer() == rb)
|
|
|
|
|
mDepthAttachment.Clear();
|
|
|
|
|
|
|
|
|
|
if (mStencilAttachment.Renderbuffer() == rb)
|
|
|
|
|
mStencilAttachment.Clear();
|
|
|
|
|
|
|
|
|
|
if (mDepthStencilAttachment.Renderbuffer() == rb)
|
|
|
|
|
mDepthStencilAttachment.Clear();
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
for (auto& cur : mMoreColorAttachments) {
|
|
|
|
|
if (cur.Renderbuffer() == rb)
|
|
|
|
|
cur.Clear();
|
2014-11-14 07:03:50 +03:00
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2014-01-23 07:59:34 +04:00
|
|
|
|
WebGLFramebuffer::HasDefinedAttachments() const
|
|
|
|
|
{
|
|
|
|
|
bool hasAttachments = false;
|
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
hasAttachments |= mColorAttachment0.IsDefined();
|
2014-01-23 07:59:34 +04:00
|
|
|
|
hasAttachments |= mDepthAttachment.IsDefined();
|
|
|
|
|
hasAttachments |= mStencilAttachment.IsDefined();
|
|
|
|
|
hasAttachments |= mDepthStencilAttachment.IsDefined();
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
for (const auto& cur : mMoreColorAttachments) {
|
|
|
|
|
hasAttachments |= cur.IsDefined();
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return hasAttachments;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2015-12-15 03:11:59 +03:00
|
|
|
|
WebGLFramebuffer::HasIncompleteAttachments(nsCString* const out_info) const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2015-12-15 03:11:59 +03:00
|
|
|
|
const auto fnIsIncomplete = [this, out_info](const WebGLFBAttachPoint& cur) {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (!cur.IsDefined())
|
|
|
|
|
return false; // Not defined, so can't count as incomplete.
|
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
return !cur.IsComplete(this->mContext, out_info);
|
2015-11-25 07:15:29 +03:00
|
|
|
|
};
|
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
bool hasIncomplete = false;
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
hasIncomplete |= fnIsIncomplete(mColorAttachment0);
|
|
|
|
|
hasIncomplete |= fnIsIncomplete(mDepthAttachment);
|
|
|
|
|
hasIncomplete |= fnIsIncomplete(mStencilAttachment);
|
|
|
|
|
hasIncomplete |= fnIsIncomplete(mDepthStencilAttachment);
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
for (const auto& cur : mMoreColorAttachments) {
|
|
|
|
|
hasIncomplete |= fnIsIncomplete(cur);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return hasIncomplete;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
static bool
|
|
|
|
|
MatchOrReplaceSize(const WebGLFBAttachPoint& cur, uint32_t* const out_width,
|
|
|
|
|
uint32_t* const out_height)
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (!cur.HasImage())
|
|
|
|
|
return true;
|
2015-11-24 08:55:59 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
uint32_t width;
|
|
|
|
|
uint32_t height;
|
|
|
|
|
cur.Size(&width, &height);
|
2015-11-24 08:55:59 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (!*out_width) {
|
|
|
|
|
MOZ_ASSERT(!*out_height);
|
|
|
|
|
*out_width = width;
|
|
|
|
|
*out_height = height;
|
|
|
|
|
return true;
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return (width == *out_width &&
|
|
|
|
|
height == *out_height);
|
2014-01-23 07:59:34 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
WebGLFramebuffer::AllImageRectsMatch() const
|
|
|
|
|
{
|
|
|
|
|
MOZ_ASSERT(HasDefinedAttachments());
|
2015-12-15 03:11:59 +03:00
|
|
|
|
DebugOnly<nsCString> fbStatusInfo;
|
|
|
|
|
MOZ_ASSERT(!HasIncompleteAttachments(&fbStatusInfo));
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
uint32_t width = 0;
|
|
|
|
|
uint32_t height = 0;
|
2014-01-23 07:59:34 +04:00
|
|
|
|
bool imageRectsMatch = true;
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
imageRectsMatch &= MatchOrReplaceSize(mColorAttachment0, &width, &height);
|
|
|
|
|
imageRectsMatch &= MatchOrReplaceSize(mDepthAttachment, &width, &height);
|
|
|
|
|
imageRectsMatch &= MatchOrReplaceSize(mStencilAttachment, &width, &height);
|
|
|
|
|
imageRectsMatch &= MatchOrReplaceSize(mDepthStencilAttachment, &width, &height);
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
for (const auto& cur : mMoreColorAttachments) {
|
|
|
|
|
imageRectsMatch &= MatchOrReplaceSize(cur, &width, &height);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return imageRectsMatch;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-25 19:21:33 +04:00
|
|
|
|
FBStatus
|
2015-12-15 03:11:59 +03:00
|
|
|
|
WebGLFramebuffer::PrecheckFramebufferStatus(nsCString* const out_info) const
|
2012-12-09 15:58:41 +04:00
|
|
|
|
{
|
2015-01-13 02:05:21 +03:00
|
|
|
|
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
|
|
|
|
|
mContext->mBoundReadFramebuffer == this);
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
|
|
|
|
if (!HasDefinedAttachments())
|
|
|
|
|
return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; // No attachments
|
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
if (HasIncompleteAttachments(out_info))
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (!mContext->IsWebGL2()) {
|
|
|
|
|
// INCOMPLETE_DIMENSIONS doesn't exist in GLES3.
|
|
|
|
|
if (!AllImageRectsMatch())
|
|
|
|
|
return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; // Inconsistent sizes
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const auto depthOrStencilCount = int(mDepthAttachment.IsDefined()) +
|
|
|
|
|
int(mStencilAttachment.IsDefined()) +
|
|
|
|
|
int(mDepthStencilAttachment.IsDefined());
|
|
|
|
|
if (depthOrStencilCount > 1)
|
|
|
|
|
return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
|
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-25 19:21:33 +04:00
|
|
|
|
FBStatus
|
2015-12-15 03:11:59 +03:00
|
|
|
|
WebGLFramebuffer::CheckFramebufferStatus(nsCString* const out_info) const
|
2014-01-23 07:59:34 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mIsKnownFBComplete)
|
|
|
|
|
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
|
2014-03-04 11:14:35 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
FBStatus ret = PrecheckFramebufferStatus(out_info);
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (ret != LOCAL_GL_FRAMEBUFFER_COMPLETE)
|
|
|
|
|
return ret;
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
// Looks good on our end. Let's ask the driver.
|
2013-10-02 04:31:37 +04:00
|
|
|
|
mContext->MakeContextCurrent();
|
|
|
|
|
|
|
|
|
|
// Ok, attach our chosen flavor of {DEPTH, STENCIL, DEPTH_STENCIL}.
|
|
|
|
|
FinalizeAttachments();
|
|
|
|
|
|
2015-02-25 01:09:09 +03:00
|
|
|
|
// TODO: This should not be unconditionally GL_FRAMEBUFFER.
|
2015-11-25 07:15:29 +03:00
|
|
|
|
ret = mContext->gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
|
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
if (ret == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
2015-11-25 07:15:29 +03:00
|
|
|
|
mIsKnownFBComplete = true;
|
2015-12-15 03:11:59 +03:00
|
|
|
|
} else {
|
|
|
|
|
out_info->AssignLiteral("Bad status according to the driver");
|
|
|
|
|
}
|
2015-11-25 07:15:29 +03:00
|
|
|
|
|
|
|
|
|
return ret;
|
2014-01-23 07:59:34 +04:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-01 06:51:43 +04:00
|
|
|
|
bool
|
2015-12-15 03:11:59 +03:00
|
|
|
|
WebGLFramebuffer::ValidateAndInitAttachments(const char* funcName)
|
2014-03-01 06:51:43 +04:00
|
|
|
|
{
|
2015-01-13 02:05:21 +03:00
|
|
|
|
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
|
|
|
|
|
mContext->mBoundReadFramebuffer == this);
|
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
nsCString fbStatusInfo;
|
|
|
|
|
const auto fbStatus = CheckFramebufferStatus(&fbStatusInfo);
|
|
|
|
|
if (fbStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
|
|
|
|
nsCString errorText = nsPrintfCString("Incomplete framebuffer: Status 0x%04x",
|
|
|
|
|
fbStatus.get());
|
|
|
|
|
if (fbStatusInfo.Length()) {
|
|
|
|
|
errorText += ": ";
|
|
|
|
|
errorText += fbStatusInfo;
|
|
|
|
|
}
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
2015-12-15 03:11:59 +03:00
|
|
|
|
mContext->ErrorInvalidFramebufferOperation("%s: %s.", funcName,
|
|
|
|
|
errorText.BeginReading());
|
2014-01-23 07:59:34 +04:00
|
|
|
|
return false;
|
2015-12-15 03:11:59 +03:00
|
|
|
|
}
|
2014-01-23 07:59:34 +04:00
|
|
|
|
|
|
|
|
|
// Cool! We've checked out ok. Just need to initialize.
|
2013-06-22 03:44:17 +04:00
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
// Check if we need to initialize anything
|
2013-06-22 03:44:17 +04:00
|
|
|
|
{
|
2014-01-23 07:59:34 +04:00
|
|
|
|
bool hasUninitializedAttachments = false;
|
2013-06-22 03:44:17 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mColorAttachment0.HasImage() && IsDrawBuffer(0))
|
2015-03-25 02:00:28 +03:00
|
|
|
|
hasUninitializedAttachments |= mColorAttachment0.HasUninitializedImageData();
|
2015-11-25 07:15:29 +03:00
|
|
|
|
|
|
|
|
|
size_t i = 1;
|
|
|
|
|
for (const auto& cur : mMoreColorAttachments) {
|
|
|
|
|
if (cur.HasImage() && IsDrawBuffer(i))
|
|
|
|
|
hasUninitializedAttachments |= cur.HasUninitializedImageData();
|
|
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
if (mDepthAttachment.HasImage())
|
|
|
|
|
hasUninitializedAttachments |= mDepthAttachment.HasUninitializedImageData();
|
|
|
|
|
if (mStencilAttachment.HasImage())
|
|
|
|
|
hasUninitializedAttachments |= mStencilAttachment.HasUninitializedImageData();
|
|
|
|
|
if (mDepthStencilAttachment.HasImage())
|
|
|
|
|
hasUninitializedAttachments |= mDepthStencilAttachment.HasUninitializedImageData();
|
|
|
|
|
|
|
|
|
|
if (!hasUninitializedAttachments)
|
2013-06-22 03:44:17 +04:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
// Get buffer-bit-mask and color-attachment-mask-list
|
2015-11-25 07:15:29 +03:00
|
|
|
|
uint32_t clearBits = 0;
|
|
|
|
|
std::vector<GLenum> tempDrawBuffers(1 + mMoreColorAttachments.Size(), LOCAL_GL_NONE);
|
2013-06-22 03:44:17 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
|
|
|
|
|
clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
|
|
|
|
|
tempDrawBuffers[0] = LOCAL_GL_COLOR_ATTACHMENT0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++i;
|
2013-06-22 03:44:17 +04:00
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2013-10-11 17:16:43 +04:00
|
|
|
|
if (mDepthAttachment.HasUninitializedImageData() ||
|
|
|
|
|
mDepthStencilAttachment.HasUninitializedImageData())
|
2012-12-09 15:58:41 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT;
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-11 17:16:43 +04:00
|
|
|
|
if (mStencilAttachment.HasUninitializedImageData() ||
|
|
|
|
|
mDepthStencilAttachment.HasUninitializedImageData())
|
2012-12-09 15:58:41 +04:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT;
|
2012-12-09 15:58:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
mContext->MakeContextCurrent();
|
|
|
|
|
|
|
|
|
|
const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) {
|
|
|
|
|
const GLenum* ptr = nullptr;
|
|
|
|
|
if (list.size()) {
|
|
|
|
|
ptr = &(list[0]);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
2015-11-25 07:15:29 +03:00
|
|
|
|
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);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
// Clear!
|
2015-11-25 07:15:29 +03:00
|
|
|
|
mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);
|
|
|
|
|
|
|
|
|
|
if (hasDrawBuffers) {
|
|
|
|
|
fnDrawBuffers(mDrawBuffers);
|
|
|
|
|
}
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2014-01-23 07:59:34 +04:00
|
|
|
|
// Mark all the uninitialized images as initialized.
|
2013-10-11 17:16:43 +04:00
|
|
|
|
if (mDepthAttachment.HasUninitializedImageData())
|
|
|
|
|
mDepthAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
|
|
|
|
|
if (mStencilAttachment.HasUninitializedImageData())
|
|
|
|
|
mStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
|
|
|
|
|
if (mDepthStencilAttachment.HasUninitializedImageData())
|
|
|
|
|
mDepthStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
|
2012-12-09 15:58:41 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
|
|
|
|
|
mColorAttachment0.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
i = 1;
|
|
|
|
|
for (auto& cur : mMoreColorAttachments) {
|
|
|
|
|
if (cur.HasUninitializedImageData() && IsDrawBuffer(i))
|
|
|
|
|
cur.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
|
2013-06-22 03:44:17 +04:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
++i;
|
2013-06-22 03:44:17 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return true;
|
2014-03-04 11:14:35 +04:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-24 08:02:07 +04:00
|
|
|
|
static void
|
2014-11-14 07:03:50 +03:00
|
|
|
|
FinalizeDrawAndReadBuffers(gl::GLContext* gl, bool isColorBufferDefined)
|
2014-01-24 08:02:07 +04:00
|
|
|
|
{
|
2014-11-14 07:03:50 +03:00
|
|
|
|
MOZ_ASSERT(gl, "Expected a valid GLContext ptr.");
|
2014-01-24 08:02:07 +04:00
|
|
|
|
// GLES don't support DrawBuffer()/ReadBuffer.
|
|
|
|
|
// According to http://www.opengl.org/wiki/Framebuffer_Object
|
|
|
|
|
//
|
|
|
|
|
// Each draw buffers must either specify color attachment points that have images
|
|
|
|
|
// attached or must be GL_NONE. (GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER when false).
|
|
|
|
|
//
|
|
|
|
|
// If the read buffer is set, then it must specify an attachment point that has an
|
|
|
|
|
// image attached. (GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER when false).
|
|
|
|
|
//
|
|
|
|
|
// Note that this test is not performed if OpenGL 4.2 or ARB_ES2_compatibility is
|
|
|
|
|
// available.
|
2014-11-14 07:03:50 +03:00
|
|
|
|
if (gl->IsGLES() ||
|
|
|
|
|
gl->IsSupported(gl::GLFeature::ES2_compatibility) ||
|
|
|
|
|
gl->IsAtLeast(gl::ContextProfile::OpenGL, 420))
|
2014-01-24 08:02:07 +04:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO(djg): Assert that fDrawBuffer/fReadBuffer is not NULL.
|
2014-11-14 07:03:50 +03:00
|
|
|
|
GLenum colorBufferSource = isColorBufferDefined ? LOCAL_GL_COLOR_ATTACHMENT0
|
|
|
|
|
: LOCAL_GL_NONE;
|
|
|
|
|
gl->fDrawBuffer(colorBufferSource);
|
|
|
|
|
gl->fReadBuffer(colorBufferSource);
|
2014-01-24 08:02:07 +04:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-02 04:30:05 +04:00
|
|
|
|
void
|
2014-01-23 07:59:34 +04:00
|
|
|
|
WebGLFramebuffer::FinalizeAttachments() const
|
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
|
|
|
|
|
mContext->mBoundReadFramebuffer == this);
|
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
|
gl::GLContext* gl = mContext->gl;
|
2014-03-12 03:10:59 +04:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
// Nuke the depth and stencil attachment points.
|
|
|
|
|
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
|
|
|
|
|
LOCAL_GL_RENDERBUFFER, 0);
|
|
|
|
|
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
|
|
|
|
|
LOCAL_GL_RENDERBUFFER, 0);
|
2015-03-17 04:22:17 +03:00
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
// Call finalize.
|
|
|
|
|
mColorAttachment0.FinalizeAttachment(gl, LOCAL_GL_COLOR_ATTACHMENT0);
|
|
|
|
|
mDepthAttachment.FinalizeAttachment(gl, LOCAL_GL_DEPTH_ATTACHMENT);
|
|
|
|
|
mStencilAttachment.FinalizeAttachment(gl, LOCAL_GL_STENCIL_ATTACHMENT);
|
|
|
|
|
mDepthStencilAttachment.FinalizeAttachment(gl, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
|
2015-03-17 07:32:52 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
for (size_t i = 0; i < mMoreColorAttachments.Size(); i++) {
|
|
|
|
|
GLenum attachPoint = LOCAL_GL_COLOR_ATTACHMENT1 + i;
|
2015-03-25 02:00:28 +03:00
|
|
|
|
mMoreColorAttachments[i].FinalizeAttachment(gl, attachPoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FinalizeDrawAndReadBuffers(gl, mColorAttachment0.IsDefined());
|
2013-10-02 04:30:05 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 03:57:05 +03:00
|
|
|
|
bool
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFramebuffer::ValidateForRead(const char* funcName,
|
|
|
|
|
const webgl::FormatUsageInfo** const out_format,
|
|
|
|
|
uint32_t* const out_width, uint32_t* const out_height)
|
2015-02-19 03:57:05 +03:00
|
|
|
|
{
|
2015-12-15 03:11:59 +03:00
|
|
|
|
if (!ValidateAndInitAttachments(funcName))
|
2015-02-19 03:57:05 +03:00
|
|
|
|
return false;
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mReadBufferMode == LOCAL_GL_NONE) {
|
|
|
|
|
mContext->ErrorInvalidOperation("%s: Read buffer mode must not be"
|
|
|
|
|
" NONE.", funcName);
|
2015-02-19 03:57:05 +03:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
const auto attachPoint = GetAttachPoint(mReadBufferMode);
|
|
|
|
|
if (!attachPoint || !attachPoint->IsDefined()) {
|
|
|
|
|
mContext->ErrorInvalidOperation("%s: The attachment specified for reading is"
|
|
|
|
|
" null.", funcName);
|
2015-02-19 03:57:05 +03:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
*out_format = attachPoint->Format();
|
|
|
|
|
attachPoint->Size(out_width, out_height);
|
2015-02-19 03:57:05 +03:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-06 09:31:00 +03:00
|
|
|
|
static bool
|
|
|
|
|
AttachmentsDontMatch(const WebGLFBAttachPoint& a, const WebGLFBAttachPoint& b)
|
|
|
|
|
{
|
|
|
|
|
if (a.Texture()) {
|
|
|
|
|
return (a.Texture() != b.Texture());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (a.Renderbuffer()) {
|
|
|
|
|
return (a.Renderbuffer() != b.Renderbuffer());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JS::Value
|
2015-11-25 07:15:29 +03:00
|
|
|
|
WebGLFramebuffer::GetAttachmentParameter(const char* funcName, JSContext* cx,
|
|
|
|
|
GLenum target, GLenum attachment,
|
|
|
|
|
GLenum pname, ErrorResult* const out_error)
|
2015-08-06 09:31:00 +03:00
|
|
|
|
{
|
2015-11-25 07:15:29 +03:00
|
|
|
|
auto attachPoint = GetAttachPoint(attachment);
|
|
|
|
|
if (!attachPoint) {
|
|
|
|
|
mContext->ErrorInvalidEnum("%s: Can only query COLOR_ATTACHMENTi,"
|
|
|
|
|
" DEPTH_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT, or"
|
|
|
|
|
" STENCIL_ATTACHMENT for a framebuffer.",
|
|
|
|
|
funcName);
|
2015-08-06 09:31:00 +03:00
|
|
|
|
return JS::NullValue();
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (mContext->IsWebGL2() && attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
|
|
|
|
// There are a couple special rules for this one.
|
2015-08-06 09:31:00 +03:00
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (pname == LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) {
|
|
|
|
|
mContext->ErrorInvalidOperation("%s: Querying"
|
|
|
|
|
" FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
|
|
|
|
|
" against DEPTH_STENCIL_ATTACHMENT is an"
|
|
|
|
|
" error.",
|
|
|
|
|
funcName);
|
2015-08-06 09:31:00 +03:00
|
|
|
|
return JS::NullValue();
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
if (AttachmentsDontMatch(DepthAttachment(), StencilAttachment())) {
|
|
|
|
|
mContext->ErrorInvalidOperation("%s: DEPTH_ATTACHMENT and STENCIL_ATTACHMENT"
|
|
|
|
|
" have different objects bound.",
|
|
|
|
|
funcName);
|
|
|
|
|
return JS::NullValue();
|
2015-08-06 09:31:00 +03:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
attachPoint = GetAttachPoint(LOCAL_GL_DEPTH_ATTACHMENT);
|
2015-08-06 09:31:00 +03:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
return attachPoint->GetParameter(funcName, mContext, cx, target, attachment, pname,
|
|
|
|
|
out_error);
|
2015-08-06 09:31:00 +03:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-25 02:00:28 +03:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Goop.
|
|
|
|
|
|
|
|
|
|
JSObject*
|
2015-07-15 03:37:28 +03:00
|
|
|
|
WebGLFramebuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
2015-03-25 02:00:28 +03:00
|
|
|
|
{
|
2015-07-15 03:37:28 +03:00
|
|
|
|
return dom::WebGLFramebufferBinding::Wrap(cx, this, givenProto);
|
2015-03-25 02:00:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-22 03:44:17 +04:00
|
|
|
|
inline void
|
2015-07-15 03:37:28 +03:00
|
|
|
|
ImplCycleCollectionUnlink(mozilla::WebGLFBAttachPoint& field)
|
2013-06-22 03:44:17 +04:00
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
field.Unlink();
|
2013-06-22 03:44:17 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void
|
2014-11-14 07:03:50 +03:00
|
|
|
|
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
|
2015-07-15 03:37:28 +03:00
|
|
|
|
mozilla::WebGLFBAttachPoint& field,
|
2014-11-14 07:03:50 +03:00
|
|
|
|
const char* name,
|
|
|
|
|
uint32_t flags = 0)
|
2013-06-22 03:44:17 +04:00
|
|
|
|
{
|
2015-03-25 02:00:28 +03:00
|
|
|
|
CycleCollectionNoteChild(callback, field.Texture(), name, flags);
|
|
|
|
|
CycleCollectionNoteChild(callback, field.Renderbuffer(), name, flags);
|
2013-06-22 03:44:17 +04:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
|
template<typename C>
|
|
|
|
|
inline void
|
|
|
|
|
ImplCycleCollectionUnlink(C& field)
|
|
|
|
|
{
|
|
|
|
|
for (auto& cur : field) {
|
|
|
|
|
cur.Unlink();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename C>
|
|
|
|
|
inline void
|
|
|
|
|
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
|
|
|
|
|
C& field,
|
|
|
|
|
const char* name,
|
|
|
|
|
uint32_t flags = 0)
|
|
|
|
|
{
|
|
|
|
|
for (auto& cur : field) {
|
|
|
|
|
ImplCycleCollectionTraverse(callback, cur, name, flags);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-29 12:57:00 +04:00
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLFramebuffer,
|
2015-03-25 02:00:28 +03:00
|
|
|
|
mColorAttachment0,
|
2014-11-14 07:03:50 +03:00
|
|
|
|
mDepthAttachment,
|
|
|
|
|
mStencilAttachment,
|
2015-03-25 02:00:28 +03:00
|
|
|
|
mDepthStencilAttachment,
|
|
|
|
|
mMoreColorAttachments)
|
2012-10-05 00:35:54 +04:00
|
|
|
|
|
2013-08-29 19:39:17 +04:00
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLFramebuffer, AddRef)
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLFramebuffer, Release)
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
|
|
|
|
} // namespace mozilla
|