void WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y, GLsizei width, GLsizei height, ErrorResult& rv) { if (IsContextLost()) return; MakeContextCurrent(); if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer")) return; const WebGLFramebuffer* fb; bool isDefaultFB; switch (target) { case LOCAL_GL_FRAMEBUFFER: case LOCAL_GL_DRAW_FRAMEBUFFER: fb = mBoundDrawFramebuffer; isDefaultFB = gl->Screen()->IsDrawFramebufferDefault(); break; case LOCAL_GL_READ_FRAMEBUFFER: fb = mBoundReadFramebuffer; isDefaultFB = gl->Screen()->IsReadFramebufferDefault(); break; default: MOZ_CRASH("Bad target."); } for (size_t i = 0; i < attachments.Length(); i++) { if (!ValidateFramebufferAttachment(fb, attachments[i], "invalidateSubFramebuffer")) { return; } } // InvalidateFramebuffer is a hint to the driver. Should be OK to // skip calls if not supported, for example by OSX 10.9 GL // drivers. static bool invalidateFBSupported = gl->IsSupported(gl::GLFeature::invalidate_framebuffer); if (!invalidateFBSupported) return; if (!fb && !isDefaultFB) { dom::Sequence<GLenum> tmpAttachments; if (!TranslateDefaultAttachments(attachments, &tmpAttachments)) { rv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } gl->fInvalidateSubFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements(), x, y, width, height); } else { gl->fInvalidateSubFramebuffer(target, attachments.Length(), attachments.Elements(), x, y, width, height); } }
void WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture* texture, GLint level, GLint layer) { if (IsContextLost()) return; if (!ValidateFramebufferTarget(target, "framebufferTextureLayer")) return; if (!ValidateTextureLayerAttachment(attachment)) return ErrorInvalidEnumInfo("framebufferTextureLayer: attachment:", attachment); if (texture) { if (texture->IsDeleted()) { return ErrorInvalidValue("framebufferTextureLayer: texture must be a valid " "texture object."); } if (layer < 0) return ErrorInvalidValue("framebufferTextureLayer: layer must be >= 0."); if (level < 0) return ErrorInvalidValue("framebufferTextureLayer: level must be >= 0."); switch (texture->Target().get()) { case LOCAL_GL_TEXTURE_3D: if (uint32_t(layer) >= mImplMax3DTextureSize) { return ErrorInvalidValue("framebufferTextureLayer: layer must be < " "MAX_3D_TEXTURE_SIZE"); } if (uint32_t(level) > FloorLog2(mImplMax3DTextureSize)) { return ErrorInvalidValue("framebufferTextureLayer: layer mube be <= " "log2(MAX_3D_TEXTURE_SIZE"); } break; case LOCAL_GL_TEXTURE_2D_ARRAY: if (uint32_t(layer) >= mImplMaxArrayTextureLayers) { return ErrorInvalidValue("framebufferTextureLayer: layer must be < " "MAX_ARRAY_TEXTURE_LAYERS"); } if (uint32_t(level) > FloorLog2(mImplMaxTextureSize)) { return ErrorInvalidValue("framebufferTextureLayer: layer mube be <= " "log2(MAX_TEXTURE_SIZE"); } break; default: return ErrorInvalidOperation("framebufferTextureLayer: texture must be an " "existing 3D texture, or a 2D texture array."); } } WebGLFramebuffer* fb; switch (target) { case LOCAL_GL_FRAMEBUFFER: case LOCAL_GL_DRAW_FRAMEBUFFER: fb = mBoundDrawFramebuffer; break; case LOCAL_GL_READ_FRAMEBUFFER: fb = mBoundReadFramebuffer; break; default: MOZ_CRASH("Bad target."); } if (!fb) { return ErrorInvalidOperation("framebufferTextureLayer: cannot modify" " framebuffer 0."); } fb->FramebufferTextureLayer(attachment, texture, level, layer); }