mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1640607 - Send SurfaceDescriptors for GPU blitting for video-to-webgl. r=lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D101061
This commit is contained in:
parent
4dd35ffb42
commit
a8926ffa47
@ -3882,7 +3882,6 @@ webgl::TexUnpackBlobDesc FromImageData(GLenum target, uvec3 size,
|
||||
Maybe<webgl::TexUnpackBlobDesc> FromDomElem(const ClientWebGLContext&,
|
||||
GLenum target, uvec3 size,
|
||||
const dom::Element& src,
|
||||
const bool allowBlitImage,
|
||||
ErrorResult* const out_error);
|
||||
} // namespace webgl
|
||||
|
||||
@ -3995,17 +3994,8 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
|
||||
}
|
||||
|
||||
if (src.mDomElem) {
|
||||
bool canUseLayerImage = true;
|
||||
if (StaticPrefs::webgl_disable_DOM_blit_uploads()) {
|
||||
canUseLayerImage = false;
|
||||
}
|
||||
if (mNotLost && mNotLost->outOfProcess) {
|
||||
canUseLayerImage = false;
|
||||
}
|
||||
|
||||
return webgl::FromDomElem(*this, imageTarget, explicitSize,
|
||||
*(src.mDomElem), canUseLayerImage,
|
||||
src.mOut_error);
|
||||
*(src.mDomElem), src.mOut_error);
|
||||
}
|
||||
|
||||
return Some(webgl::TexUnpackBlobDesc{
|
||||
@ -4021,20 +4011,17 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
|
||||
// UNPACK_ALIGNMENT are not strictly defined. These restrictions ensure
|
||||
// consistent and efficient behavior regardless of implied UNPACK_ params.
|
||||
|
||||
Maybe<gfx::IntSize> structuredSrcSize;
|
||||
if (desc->surf) {
|
||||
structuredSrcSize = Some(desc->surf->GetSize());
|
||||
}
|
||||
if (desc->image) {
|
||||
structuredSrcSize = Some(desc->image->GetSize());
|
||||
Maybe<uvec2> structuredSrcSize;
|
||||
if (desc->dataSurf || desc->sd) {
|
||||
structuredSrcSize = Some(desc->imageSize);
|
||||
}
|
||||
if (structuredSrcSize) {
|
||||
auto& size = desc->size;
|
||||
if (!size.x) {
|
||||
size.x = structuredSrcSize->width;
|
||||
size.x = structuredSrcSize->x;
|
||||
}
|
||||
if (!size.y) {
|
||||
size.y = structuredSrcSize->height;
|
||||
size.y = structuredSrcSize->x;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4057,7 +4044,50 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
|
||||
|
||||
// -
|
||||
|
||||
if (desc->sd) {
|
||||
auto fallbackReason = BlitPreventReason(level, offset, pi, *desc);
|
||||
|
||||
const auto& sd = *(desc->sd);
|
||||
const auto sdType = sd.type();
|
||||
const auto& contextInfo = mNotLost->info;
|
||||
|
||||
const bool canUploadViaSd = contextInfo.uploadableSdTypes[sdType];
|
||||
if (!canUploadViaSd) {
|
||||
const nsPrintfCString msg(
|
||||
"Fast uploads for resource type %i not implemented.", int(sdType));
|
||||
fallbackReason.reset();
|
||||
fallbackReason.emplace(ToString(msg));
|
||||
}
|
||||
|
||||
if (StaticPrefs::webgl_disable_DOM_blit_uploads()) {
|
||||
fallbackReason.reset();
|
||||
fallbackReason.emplace("DOM blit uploads are disabled.");
|
||||
}
|
||||
|
||||
if (fallbackReason) {
|
||||
EnqueuePerfWarning("Missed GPU-copy fast-path: %s",
|
||||
fallbackReason->c_str());
|
||||
|
||||
const auto& image = desc->image;
|
||||
const RefPtr<gfx::SourceSurface> surf = image->GetAsSourceSurface();
|
||||
if (surf) {
|
||||
// WARNING: OSX can lose our MakeCurrent here.
|
||||
desc->dataSurf = surf->GetDataSurface();
|
||||
}
|
||||
if (!desc->dataSurf) {
|
||||
EnqueueError(LOCAL_GL_OUT_OF_MEMORY,
|
||||
"Failed to retrieve source bytes for CPU upload.");
|
||||
return;
|
||||
}
|
||||
desc->sd = Nothing();
|
||||
}
|
||||
}
|
||||
desc->image = nullptr;
|
||||
|
||||
// -
|
||||
|
||||
desc->Shrink(pi);
|
||||
|
||||
Run<RPROC(TexImage)>(static_cast<uint32_t>(level), respecFormat,
|
||||
CastUvec3(offset), pi, std::move(*desc));
|
||||
scopedArr.Reset(); // (For the hazard analysis) Done with the data.
|
||||
|
@ -877,6 +877,11 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
|
||||
EnqueueError(0, format, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void EnqueuePerfWarning(const char* const format, const Args&... args) const {
|
||||
EnqueueError(webgl::kErrorPerfWarning, format, args...);
|
||||
}
|
||||
|
||||
void EnqueueError_ArgEnum(const char* argName,
|
||||
GLenum val) const; // Cold code.
|
||||
|
||||
|
@ -398,24 +398,25 @@ struct QueueParamTraits<webgl::TexUnpackBlobDesc> {
|
||||
|
||||
template <typename U>
|
||||
static QueueStatus Write(ProducerView<U>& view, const ParamType& in) {
|
||||
MOZ_ASSERT(!in.image);
|
||||
const bool isSurf = bool(in.surf);
|
||||
MOZ_RELEASE_ASSERT(!in.image);
|
||||
const bool isDataSurf = bool(in.dataSurf);
|
||||
if (!view.WriteParam(in.imageTarget) || !view.WriteParam(in.size) ||
|
||||
!view.WriteParam(in.srcAlphaType) || !view.WriteParam(in.unpacking) ||
|
||||
!view.WriteParam(in.cpuData) || !view.WriteParam(in.pboOffset) ||
|
||||
!view.WriteParam(isSurf)) {
|
||||
!view.WriteParam(in.imageSize) || !view.WriteParam(in.sd) ||
|
||||
!view.WriteParam(isDataSurf)) {
|
||||
return view.GetStatus();
|
||||
}
|
||||
if (isSurf) {
|
||||
gfx::DataSourceSurface::ScopedMap map(in.surf,
|
||||
gfx::DataSourceSurface::READ);
|
||||
if (isDataSurf) {
|
||||
const auto& surf = in.dataSurf;
|
||||
gfx::DataSourceSurface::ScopedMap map(surf, gfx::DataSourceSurface::READ);
|
||||
if (!map.IsMapped()) {
|
||||
return QueueStatus::kOOMError;
|
||||
}
|
||||
const auto& surfSize = in.surf->GetSize();
|
||||
const auto& surfSize = surf->GetSize();
|
||||
const auto stride = *MaybeAs<size_t>(map.GetStride());
|
||||
if (!view.WriteParam(surfSize) ||
|
||||
!view.WriteParam(in.surf->GetFormat()) || !view.WriteParam(stride)) {
|
||||
if (!view.WriteParam(surfSize) || !view.WriteParam(surf->GetFormat()) ||
|
||||
!view.WriteParam(stride)) {
|
||||
return view.GetStatus();
|
||||
}
|
||||
|
||||
@ -430,14 +431,15 @@ struct QueueParamTraits<webgl::TexUnpackBlobDesc> {
|
||||
|
||||
template <typename U>
|
||||
static QueueStatus Read(ConsumerView<U>& view, ParamType* const out) {
|
||||
bool isSurf;
|
||||
bool isDataSurf;
|
||||
if (!view.ReadParam(&out->imageTarget) || !view.ReadParam(&out->size) ||
|
||||
!view.ReadParam(&out->srcAlphaType) ||
|
||||
!view.ReadParam(&out->unpacking) || !view.ReadParam(&out->cpuData) ||
|
||||
!view.ReadParam(&out->pboOffset) || !view.ReadParam(&isSurf)) {
|
||||
!view.ReadParam(&out->pboOffset) || !view.ReadParam(&out->imageSize) ||
|
||||
!view.ReadParam(&out->sd) || !view.ReadParam(&isDataSurf)) {
|
||||
return view.GetStatus();
|
||||
}
|
||||
if (isSurf) {
|
||||
if (isDataSurf) {
|
||||
gfx::IntSize surfSize;
|
||||
gfx::SurfaceFormat format;
|
||||
size_t stride;
|
||||
@ -445,13 +447,14 @@ struct QueueParamTraits<webgl::TexUnpackBlobDesc> {
|
||||
!view.ReadParam(&stride)) {
|
||||
return view.GetStatus();
|
||||
}
|
||||
out->surf = gfx::Factory::CreateDataSourceSurfaceWithStride(
|
||||
surfSize, format, stride, true);
|
||||
if (!out->surf) {
|
||||
auto& surf = out->dataSurf;
|
||||
surf = gfx::Factory::CreateDataSourceSurfaceWithStride(surfSize, format,
|
||||
stride, true);
|
||||
if (!surf) {
|
||||
return QueueStatus::kOOMError;
|
||||
}
|
||||
|
||||
gfx::DataSourceSurface::ScopedMap map(out->surf,
|
||||
gfx::DataSourceSurface::ScopedMap map(surf,
|
||||
gfx::DataSourceSurface::WRITE);
|
||||
if (!map.IsMapped()) {
|
||||
return QueueStatus::kOOMError;
|
||||
|
@ -358,10 +358,10 @@ std::unique_ptr<TexUnpackBlob> TexUnpackBlob::Create(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (desc.image) {
|
||||
if (desc.sd) {
|
||||
return new TexUnpackImage(desc);
|
||||
}
|
||||
if (desc.surf) {
|
||||
if (desc.dataSurf) {
|
||||
return new TexUnpackSurface(desc);
|
||||
}
|
||||
|
||||
@ -675,10 +675,59 @@ bool TexUnpackImage::Validate(const WebGLContext* const webgl,
|
||||
const webgl::PackingInfo& pi) {
|
||||
if (!ValidatePIForDOM(webgl, pi)) return false;
|
||||
|
||||
const auto fullRows = mDesc.image->GetSize().height;
|
||||
const auto fullRows = mDesc.imageSize.y;
|
||||
return ValidateUnpackPixels(webgl, fullRows, 0, this);
|
||||
}
|
||||
|
||||
Maybe<std::string> BlitPreventReason(const int32_t level, const ivec3& offset,
|
||||
const webgl::PackingInfo& pi,
|
||||
const TexUnpackBlobDesc& desc) {
|
||||
const auto& size = desc.size;
|
||||
const auto& unpacking = desc.unpacking;
|
||||
|
||||
const auto ret = [&]() -> const char* {
|
||||
if (size.z != 1) {
|
||||
return "depth is not 1";
|
||||
}
|
||||
if (offset.x != 0 || offset.y != 0 || offset.z != 0) {
|
||||
return "x/y/zOffset is not 0";
|
||||
}
|
||||
|
||||
if (unpacking.mUnpackSkipPixels || unpacking.mUnpackSkipRows ||
|
||||
unpacking.mUnpackSkipImages) {
|
||||
return "non-zero UNPACK_SKIP_* not yet supported";
|
||||
}
|
||||
|
||||
const auto premultReason = [&]() -> const char* {
|
||||
if (desc.srcAlphaType == gfxAlphaType::Opaque) return nullptr;
|
||||
|
||||
const bool srcIsPremult = (desc.srcAlphaType == gfxAlphaType::Premult);
|
||||
const auto& dstIsPremult = unpacking.mPremultiplyAlpha;
|
||||
if (srcIsPremult == dstIsPremult) return nullptr;
|
||||
|
||||
if (dstIsPremult) {
|
||||
return "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not true";
|
||||
} else {
|
||||
return "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not false";
|
||||
}
|
||||
}();
|
||||
if (premultReason) return premultReason;
|
||||
|
||||
if (pi.format != LOCAL_GL_RGBA) {
|
||||
return "`format` is not RGBA";
|
||||
}
|
||||
|
||||
if (pi.type != LOCAL_GL_UNSIGNED_BYTE) {
|
||||
return "`type` is not UNSIGNED_BYTE";
|
||||
}
|
||||
return nullptr;
|
||||
}();
|
||||
if (ret) {
|
||||
return Some(std::string(ret));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
|
||||
WebGLTexture* tex, GLint level,
|
||||
const webgl::DriverUnpackInfo* dui,
|
||||
@ -690,11 +739,25 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
|
||||
const auto& webgl = tex->mContext;
|
||||
const auto& target = mDesc.imageTarget;
|
||||
const auto& size = mDesc.size;
|
||||
const auto& image = mDesc.image;
|
||||
const auto& sd = *(mDesc.sd);
|
||||
const auto& unpacking = mDesc.unpacking;
|
||||
|
||||
const auto& gl = webgl->GL();
|
||||
|
||||
// -
|
||||
|
||||
const auto reason =
|
||||
BlitPreventReason(level, {xOffset, yOffset, zOffset}, pi, mDesc);
|
||||
if (reason) {
|
||||
webgl->GeneratePerfWarning(
|
||||
"Failed to hit GPU-copy fast-path."
|
||||
" (%s) Falling back to CPU upload.",
|
||||
reason->c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
if (needsRespec) {
|
||||
*out_error =
|
||||
DoTexOrSubImage(isSubImage, gl, target, level, dui, xOffset, yOffset,
|
||||
@ -702,50 +765,7 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
|
||||
if (*out_error) return true;
|
||||
}
|
||||
|
||||
const char* fallbackReason;
|
||||
do {
|
||||
if (size.z != 1) {
|
||||
fallbackReason = "depth is not 1";
|
||||
break;
|
||||
}
|
||||
if (xOffset != 0 || yOffset != 0 || zOffset != 0) {
|
||||
fallbackReason = "x/y/zOffset is not 0";
|
||||
break;
|
||||
}
|
||||
|
||||
if (unpacking.mUnpackSkipPixels || unpacking.mUnpackSkipRows ||
|
||||
unpacking.mUnpackSkipImages) {
|
||||
fallbackReason = "non-zero UNPACK_SKIP_* not yet supported";
|
||||
break;
|
||||
}
|
||||
|
||||
const auto fnHasPremultMismatch = [&]() {
|
||||
if (mDesc.srcAlphaType == gfxAlphaType::Opaque) return false;
|
||||
|
||||
const bool srcIsPremult = (mDesc.srcAlphaType == gfxAlphaType::Premult);
|
||||
const auto& dstIsPremult = unpacking.mPremultiplyAlpha;
|
||||
if (srcIsPremult == dstIsPremult) return false;
|
||||
|
||||
if (dstIsPremult) {
|
||||
fallbackReason = "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not true";
|
||||
} else {
|
||||
fallbackReason = "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not false";
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (fnHasPremultMismatch()) break;
|
||||
|
||||
if (dui->unpackFormat != LOCAL_GL_RGB &&
|
||||
dui->unpackFormat != LOCAL_GL_RGBA) {
|
||||
fallbackReason = "`format` is not RGB or RGBA";
|
||||
break;
|
||||
}
|
||||
|
||||
if (dui->unpackType != LOCAL_GL_UNSIGNED_BYTE) {
|
||||
fallbackReason = "`type` is not UNSIGNED_BYTE";
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
gl::ScopedFramebuffer scopedFB(gl);
|
||||
gl::ScopedBindFramebuffer bindFB(gl, scopedFB.FB());
|
||||
|
||||
@ -756,62 +776,24 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
|
||||
LOCAL_GL_COLOR_ATTACHMENT0, target,
|
||||
tex->mGLName, level);
|
||||
|
||||
if (errorScope.GetError()) {
|
||||
fallbackReason = "bug: failed to attach to FB for blit";
|
||||
break;
|
||||
}
|
||||
const auto err = errorScope.GetError();
|
||||
MOZ_ALWAYS_TRUE(!err);
|
||||
}
|
||||
|
||||
const GLenum status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
|
||||
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
||||
fallbackReason = "bug: failed to confirm FB for blit";
|
||||
break;
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
const auto dstOrigin =
|
||||
(unpacking.mFlipY ? gl::OriginPos::TopLeft : gl::OriginPos::BottomLeft);
|
||||
if (!gl->BlitHelper()->BlitImageToFramebuffer(image, {size.x, size.y},
|
||||
dstOrigin)) {
|
||||
fallbackReason = "likely bug: failed to blit";
|
||||
break;
|
||||
if (!gl->BlitHelper()->BlitSdToFramebuffer(sd, {size.x, size.y},
|
||||
dstOrigin)) {
|
||||
webgl->ErrorImplementationBug("BlitSdToFramebuffer failed for type %i.",
|
||||
int(sd.type()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Blitting was successful, so we're done!
|
||||
*out_error = 0;
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
const nsPrintfCString perfMsg(
|
||||
"Failed to hit GPU-copy fast-path: %s (src type %u)", fallbackReason,
|
||||
uint32_t(image->GetFormat()));
|
||||
|
||||
if (unpacking.mRequireFastPath) {
|
||||
webgl->ErrorInvalidOperation("%s", perfMsg.BeginReading());
|
||||
return false;
|
||||
}
|
||||
|
||||
webgl->GeneratePerfWarning("%s Falling back to CPU upload.",
|
||||
perfMsg.BeginReading());
|
||||
|
||||
const RefPtr<gfx::SourceSurface> surf = image->GetAsSourceSurface();
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> dataSurf;
|
||||
if (surf) {
|
||||
// WARNING: OSX can lose our MakeCurrent here.
|
||||
dataSurf = surf->GetDataSurface();
|
||||
}
|
||||
if (!dataSurf) {
|
||||
webgl->ErrorOutOfMemory(
|
||||
"GetAsSourceSurface or GetDataSurface failed after"
|
||||
" blit failed for TexUnpackImage.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const TexUnpackBlobDesc newDesc = {
|
||||
target, size, mDesc.srcAlphaType, {}, {}, {}, dataSurf, unpacking};
|
||||
const TexUnpackSurface surfBlob(newDesc);
|
||||
return surfBlob.TexOrSubImage(isSubImage, needsRespec, tex, level, dui,
|
||||
xOffset, yOffset, zOffset, pi, out_error);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -875,7 +857,7 @@ bool TexUnpackSurface::Validate(const WebGLContext* const webgl,
|
||||
const webgl::PackingInfo& pi) {
|
||||
if (!ValidatePIForDOM(webgl, pi)) return false;
|
||||
|
||||
const auto fullRows = mDesc.surf->GetSize().height;
|
||||
const auto fullRows = mDesc.dataSurf->GetSize().height;
|
||||
return ValidateUnpackPixels(webgl, fullRows, 0, this);
|
||||
}
|
||||
|
||||
@ -888,7 +870,7 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
|
||||
GLenum* const out_error) const {
|
||||
const auto& webgl = tex->mContext;
|
||||
const auto& size = mDesc.size;
|
||||
auto& surf = *(mDesc.surf);
|
||||
auto& surf = *(mDesc.dataSurf);
|
||||
|
||||
////
|
||||
|
||||
|
@ -41,6 +41,10 @@ namespace webgl {
|
||||
struct PackingInfo;
|
||||
struct DriverUnpackInfo;
|
||||
|
||||
Maybe<std::string> BlitPreventReason(int32_t level, const ivec3& offset,
|
||||
const webgl::PackingInfo&,
|
||||
const TexUnpackBlobDesc&);
|
||||
|
||||
class TexUnpackBlob {
|
||||
public:
|
||||
const TexUnpackBlobDesc& mDesc;
|
||||
|
@ -588,8 +588,25 @@ RefPtr<WebGLContext> WebGLContext::Create(HostWebGLContext& host,
|
||||
printf_stderr("--- WebGL context created: %p\n", webgl.get());
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
const auto UploadableSdTypes = [&]() {
|
||||
webgl::EnumMask<layers::SurfaceDescriptor::Type> types;
|
||||
if (webgl->gl->IsANGLE()) {
|
||||
types[layers::SurfaceDescriptor::TSurfaceDescriptorD3D10] = true;
|
||||
types[layers::SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr] = true;
|
||||
}
|
||||
if (kIsMacOS) {
|
||||
types[layers::SurfaceDescriptor::TSurfaceDescriptorMacIOSurface] = true;
|
||||
}
|
||||
return types;
|
||||
};
|
||||
|
||||
// -
|
||||
|
||||
out->options = webgl->mOptions;
|
||||
out->limits = *webgl->mLimits;
|
||||
out->uploadableSdTypes = UploadableSdTypes();
|
||||
|
||||
return webgl;
|
||||
}
|
||||
@ -1398,8 +1415,8 @@ const char* WebGLContext::FuncName() const {
|
||||
if (MOZ_LIKELY(mFuncScope)) {
|
||||
ret = mFuncScope->mFuncName;
|
||||
} else {
|
||||
MOZ_ASSERT(false, "FuncScope not on stack!");
|
||||
ret = "<funcName unknown>";
|
||||
NS_WARNING("FuncScope not on stack!");
|
||||
ret = "<unknown function>";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1504,12 +1521,20 @@ nsresult webgl::AvailabilityRunnable::Run() {
|
||||
|
||||
// -
|
||||
|
||||
void WebGLContext::GenerateErrorImpl(const GLenum err,
|
||||
void WebGLContext::GenerateErrorImpl(const GLenum errOrWarning,
|
||||
const std::string& text) const {
|
||||
if (mFuncScope && mFuncScope->mBindFailureGuard) {
|
||||
auto err = errOrWarning;
|
||||
bool isPerfWarning = false;
|
||||
if (err == webgl::kErrorPerfWarning) {
|
||||
err = 0;
|
||||
isPerfWarning = true;
|
||||
}
|
||||
|
||||
if (err && mFuncScope && mFuncScope->mBindFailureGuard) {
|
||||
gfxCriticalError() << "mBindFailureGuard failure: Generating error "
|
||||
<< EnumString(err) << ": " << text;
|
||||
}
|
||||
|
||||
/* ES2 section 2.5 "GL Errors" states that implementations can have
|
||||
* multiple 'flags', as errors might be caught in different parts of
|
||||
* a distributed implementation.
|
||||
@ -1520,18 +1545,39 @@ void WebGLContext::GenerateErrorImpl(const GLenum err,
|
||||
|
||||
if (!mHost) return; // Impossible?
|
||||
|
||||
if (!ShouldGenerateWarnings()) return;
|
||||
// -
|
||||
|
||||
mHost->JsWarning(text);
|
||||
mWarningCount += 1;
|
||||
const auto ShouldWarn = [&]() {
|
||||
if (isPerfWarning) {
|
||||
return ShouldGeneratePerfWarnings();
|
||||
}
|
||||
return ShouldGenerateWarnings();
|
||||
};
|
||||
if (!ShouldWarn()) return;
|
||||
|
||||
if (!ShouldGenerateWarnings()) {
|
||||
auto info = std::string(
|
||||
"WebGL: No further warnings will be reported for this WebGL "
|
||||
"context. (already reported ");
|
||||
info += std::to_string(mWarningCount);
|
||||
info += " warnings)";
|
||||
mHost->JsWarning(info);
|
||||
// -
|
||||
|
||||
auto* pNumWarnings = &mWarningCount;
|
||||
const char* warningsType = "warnings";
|
||||
if (isPerfWarning) {
|
||||
pNumWarnings = &mNumPerfWarnings;
|
||||
warningsType = "perf warnings";
|
||||
}
|
||||
|
||||
if (isPerfWarning) {
|
||||
const auto perfText = std::string("WebGL perf warning: ") + text;
|
||||
mHost->JsWarning(perfText);
|
||||
} else {
|
||||
mHost->JsWarning(text);
|
||||
}
|
||||
*pNumWarnings += 1;
|
||||
|
||||
if (!ShouldWarn()) {
|
||||
const auto& msg = nsPrintfCString(
|
||||
"After reporting %i, no further %s will be reported for this WebGL "
|
||||
"context.",
|
||||
int(*pNumWarnings), warningsType);
|
||||
mHost->JsWarning(ToString(msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1237,35 +1237,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
|
||||
|
||||
template <typename... Args>
|
||||
void GeneratePerfWarning(const char* const fmt, const Args&... args) const {
|
||||
if (!ShouldGeneratePerfWarnings()) return;
|
||||
|
||||
const auto funcName = FuncName();
|
||||
nsCString msg;
|
||||
msg.AppendPrintf("WebGL perf warning: %s: ", funcName);
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wformat-security"
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif
|
||||
msg.AppendPrintf(fmt, args...);
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
GenerateErrorImpl(0, msg);
|
||||
|
||||
mNumPerfWarnings++;
|
||||
if (!ShouldGeneratePerfWarnings()) {
|
||||
GenerateWarning(
|
||||
"After reporting %u, no further WebGL perf warnings will"
|
||||
" be reported for this WebGL context.",
|
||||
uint32_t(mNumPerfWarnings));
|
||||
}
|
||||
GenerateError(webgl::kErrorPerfWarning, fmt, args...);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -226,6 +226,10 @@ struct ParamTraits<mozilla::webgl::OpaqueFramebufferOptions> final
|
||||
|
||||
// -
|
||||
|
||||
template <typename T>
|
||||
struct ParamTraits<mozilla::webgl::EnumMask<T>> final
|
||||
: public PlainOldDataSerializer<mozilla::webgl::EnumMask<T>> {};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::webgl::InitContextResult> final {
|
||||
using T = mozilla::webgl::InitContextResult;
|
||||
@ -234,13 +238,15 @@ struct ParamTraits<mozilla::webgl::InitContextResult> final {
|
||||
WriteParam(msg, in.error);
|
||||
WriteParam(msg, in.options);
|
||||
WriteParam(msg, in.limits);
|
||||
WriteParam(msg, in.uploadableSdTypes);
|
||||
}
|
||||
|
||||
static bool Read(const Message* const msg, PickleIterator* const itr,
|
||||
T* const out) {
|
||||
return ReadParam(msg, itr, &out->error) &&
|
||||
ReadParam(msg, itr, &out->options) &&
|
||||
ReadParam(msg, itr, &out->limits);
|
||||
ReadParam(msg, itr, &out->limits) &&
|
||||
ReadParam(msg, itr, &out->uploadableSdTypes);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -68,6 +68,8 @@ struct IsTriviallySerializable<webgl::VertAttribPointerDesc> : std::true_type {
|
||||
};
|
||||
template <>
|
||||
struct IsTriviallySerializable<webgl::ReadPixelsDesc> : std::true_type {};
|
||||
template <>
|
||||
struct IsTriviallySerializable<layers::SurfaceDescriptor> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct QueueParamTraits<RawBuffer<T>> {
|
||||
|
@ -50,20 +50,28 @@ Maybe<TexUnpackBlobDesc> FromImageBitmap(const GLenum target, uvec3 size,
|
||||
}
|
||||
|
||||
const RefPtr<gfx::DataSourceSurface> surf = cloneData->mSurface;
|
||||
const auto imageSize = *uvec2::FromSize(surf->GetSize());
|
||||
|
||||
if (!size.x) {
|
||||
size.x = surf->GetSize().width;
|
||||
size.x = imageSize.x;
|
||||
}
|
||||
|
||||
if (!size.y) {
|
||||
size.y = surf->GetSize().height;
|
||||
size.y = imageSize.y;
|
||||
}
|
||||
|
||||
// WhatWG "HTML Living Standard" (30 October 2015):
|
||||
// "The getImageData(sx, sy, sw, sh) method [...] Pixels must be returned as
|
||||
// non-premultiplied alpha values."
|
||||
return Some(
|
||||
TexUnpackBlobDesc{target, size, cloneData->mAlphaType, {}, {}, {}, surf});
|
||||
return Some(TexUnpackBlobDesc{target,
|
||||
size,
|
||||
cloneData->mAlphaType,
|
||||
{},
|
||||
{},
|
||||
imageSize,
|
||||
nullptr,
|
||||
{},
|
||||
surf});
|
||||
}
|
||||
|
||||
TexUnpackBlobDesc FromImageData(const GLenum target, uvec3 size,
|
||||
@ -74,24 +82,25 @@ TexUnpackBlobDesc FromImageData(const GLenum target, uvec3 size,
|
||||
const size_t dataSize = scopedArr->Length();
|
||||
const auto data = reinterpret_cast<uint8_t*>(scopedArr->Data());
|
||||
|
||||
const gfx::IntSize imageSize(imageData.Width(), imageData.Height());
|
||||
const size_t stride = imageSize.width * 4;
|
||||
const gfx::IntSize imageISize(imageData.Width(), imageData.Height());
|
||||
const auto imageUSize = *uvec2::FromSize(imageISize);
|
||||
const size_t stride = imageUSize.x * 4;
|
||||
const gfx::SurfaceFormat surfFormat = gfx::SurfaceFormat::R8G8B8A8;
|
||||
MOZ_ALWAYS_TRUE(dataSize == stride * imageSize.height);
|
||||
MOZ_ALWAYS_TRUE(dataSize == stride * imageUSize.y);
|
||||
|
||||
const RefPtr<gfx::DataSourceSurface> surf =
|
||||
gfx::Factory::CreateWrappingDataSourceSurface(data, stride, imageSize,
|
||||
gfx::Factory::CreateWrappingDataSourceSurface(data, stride, imageISize,
|
||||
surfFormat);
|
||||
MOZ_ASSERT(surf);
|
||||
|
||||
////
|
||||
|
||||
if (!size.x) {
|
||||
size.x = imageData.Width();
|
||||
size.x = imageUSize.x;
|
||||
}
|
||||
|
||||
if (!size.y) {
|
||||
size.y = imageData.Height();
|
||||
size.y = imageUSize.y;
|
||||
}
|
||||
|
||||
////
|
||||
@ -99,13 +108,46 @@ TexUnpackBlobDesc FromImageData(const GLenum target, uvec3 size,
|
||||
// WhatWG "HTML Living Standard" (30 October 2015):
|
||||
// "The getImageData(sx, sy, sw, sh) method [...] Pixels must be returned as
|
||||
// non-premultiplied alpha values."
|
||||
return {target, size, gfxAlphaType::NonPremult, {}, {}, {}, surf};
|
||||
return {target, size, gfxAlphaType::NonPremult, {}, {}, imageUSize, nullptr,
|
||||
{}, surf};
|
||||
}
|
||||
|
||||
static layers::SurfaceDescriptor Flatten(const layers::SurfaceDescriptor& sd) {
|
||||
const auto sdType = sd.type();
|
||||
if (sdType != layers::SurfaceDescriptor::TSurfaceDescriptorGPUVideo) {
|
||||
return sd;
|
||||
}
|
||||
const auto& sdv = sd.get_SurfaceDescriptorGPUVideo();
|
||||
const auto& sdvType = sdv.type();
|
||||
if (sdvType !=
|
||||
layers::SurfaceDescriptorGPUVideo::TSurfaceDescriptorRemoteDecoder) {
|
||||
return sd;
|
||||
}
|
||||
|
||||
const auto& sdrd = sdv.get_SurfaceDescriptorRemoteDecoder();
|
||||
const auto& subdesc = sdrd.subdesc();
|
||||
const auto& subdescType = subdesc.type();
|
||||
switch (subdescType) {
|
||||
case layers::RemoteDecoderVideoSubDescriptor::T__None:
|
||||
case layers::RemoteDecoderVideoSubDescriptor::Tnull_t:
|
||||
return sd;
|
||||
|
||||
case layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorD3D10:
|
||||
return subdesc.get_SurfaceDescriptorD3D10();
|
||||
case layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorDXGIYCbCr:
|
||||
return subdesc.get_SurfaceDescriptorDXGIYCbCr();
|
||||
case layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorDMABuf:
|
||||
return subdesc.get_SurfaceDescriptorDMABuf();
|
||||
case layers::RemoteDecoderVideoSubDescriptor::
|
||||
TSurfaceDescriptorMacIOSurface:
|
||||
return subdesc.get_SurfaceDescriptorMacIOSurface();
|
||||
}
|
||||
MOZ_CRASH("unreachable");
|
||||
}
|
||||
|
||||
Maybe<webgl::TexUnpackBlobDesc> FromDomElem(const ClientWebGLContext& webgl,
|
||||
const GLenum target, uvec3 size,
|
||||
const dom::Element& elem,
|
||||
const bool allowBlitImage,
|
||||
ErrorResult* const out_error) {
|
||||
const auto& canvas = *webgl.GetCanvas();
|
||||
|
||||
@ -136,21 +178,23 @@ Maybe<webgl::TexUnpackBlobDesc> FromDomElem(const ClientWebGLContext& webgl,
|
||||
|
||||
//////
|
||||
|
||||
uint32_t elemWidth = 0;
|
||||
uint32_t elemHeight = 0;
|
||||
layers::Image* layersImage = nullptr;
|
||||
uvec2 elemSize;
|
||||
|
||||
if (sfer.mLayersImage && allowBlitImage) {
|
||||
layersImage = sfer.mLayersImage;
|
||||
elemWidth = layersImage->GetSize().width;
|
||||
elemHeight = layersImage->GetSize().height;
|
||||
const auto& layersImage = sfer.mLayersImage;
|
||||
Maybe<layers::SurfaceDescriptor> sd;
|
||||
if (layersImage) {
|
||||
elemSize = *uvec2::FromSize(layersImage->GetSize());
|
||||
|
||||
sd = layersImage->GetDesc();
|
||||
if (sd) {
|
||||
sd = Some(Flatten(*sd));
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> dataSurf;
|
||||
if (!layersImage && sfer.GetSourceSurface()) {
|
||||
if (!sd && sfer.GetSourceSurface()) {
|
||||
const auto surf = sfer.GetSourceSurface();
|
||||
elemWidth = surf->GetSize().width;
|
||||
elemHeight = surf->GetSize().height;
|
||||
elemSize = *uvec2::FromSize(surf->GetSize());
|
||||
|
||||
// WARNING: OSX can lose our MakeCurrent here.
|
||||
dataSurf = surf->GetDataSurface();
|
||||
@ -159,16 +203,17 @@ Maybe<webgl::TexUnpackBlobDesc> FromDomElem(const ClientWebGLContext& webgl,
|
||||
//////
|
||||
|
||||
if (!size.x) {
|
||||
size.x = elemWidth;
|
||||
size.x = elemSize.x;
|
||||
}
|
||||
|
||||
if (!size.y) {
|
||||
size.y = elemHeight;
|
||||
size.y = elemSize.y;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
if (!layersImage && !dataSurf) {
|
||||
webgl.EnqueueWarning("Resource has no data (yet?). Uploading zeros.");
|
||||
return Some(TexUnpackBlobDesc{target, size, gfxAlphaType::NonPremult});
|
||||
}
|
||||
|
||||
@ -201,14 +246,15 @@ Maybe<webgl::TexUnpackBlobDesc> FromDomElem(const ClientWebGLContext& webgl,
|
||||
//////
|
||||
// Ok, we're good!
|
||||
|
||||
if (layersImage) {
|
||||
return Some(
|
||||
TexUnpackBlobDesc{target, size, sfer.mAlphaType, {}, {}, layersImage});
|
||||
}
|
||||
|
||||
MOZ_ASSERT(dataSurf);
|
||||
return Some(
|
||||
TexUnpackBlobDesc{target, size, sfer.mAlphaType, {}, {}, {}, dataSurf});
|
||||
return Some(TexUnpackBlobDesc{target,
|
||||
size,
|
||||
sfer.mAlphaType,
|
||||
{},
|
||||
{},
|
||||
elemSize,
|
||||
layersImage,
|
||||
sd,
|
||||
dataSurf});
|
||||
}
|
||||
|
||||
} // namespace webgl
|
||||
@ -867,8 +913,9 @@ void WebGLTexture::TexImage(uint32_t level, GLenum respecFormat,
|
||||
cpuDataView = Some(RawBuffer<>{src.cpuData->Data()});
|
||||
}
|
||||
const auto srcViewDesc = webgl::TexUnpackBlobDesc{
|
||||
src.imageTarget, src.size, src.srcAlphaType, std::move(cpuDataView),
|
||||
src.pboOffset, src.image, src.surf, src.unpacking};
|
||||
src.imageTarget, src.size, src.srcAlphaType, std::move(cpuDataView),
|
||||
src.pboOffset, src.imageSize, src.image, src.sd,
|
||||
src.dataSurf, src.unpacking};
|
||||
const auto blob = webgl::TexUnpackBlob::Create(srcViewDesc);
|
||||
if (!blob) {
|
||||
MOZ_ASSERT(false);
|
||||
@ -1020,7 +1067,7 @@ void WebGLTexture::TexImage(uint32_t level, GLenum respecFormat,
|
||||
});
|
||||
|
||||
const bool isSubImage = !respecFormat;
|
||||
GLenum glError;
|
||||
GLenum glError = 0;
|
||||
if (!blob->TexOrSubImage(isSubImage, isRespec, this, level, driverUnpackInfo,
|
||||
offset.x, offset.y, offset.z, pi, &glError)) {
|
||||
return;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
#include "gfxTypes.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
@ -298,6 +299,8 @@ class UniqueBuffer {
|
||||
namespace webgl {
|
||||
struct FormatUsageInfo;
|
||||
|
||||
static constexpr GLenum kErrorPerfWarning = 0x10001;
|
||||
|
||||
struct SampleableInfo final {
|
||||
const char* incompleteReason = nullptr;
|
||||
uint32_t levels = 0;
|
||||
@ -536,11 +539,16 @@ struct ReadPixelsDesc final {
|
||||
PixelPackState packState;
|
||||
};
|
||||
|
||||
class ExtensionBits final {
|
||||
// -
|
||||
|
||||
template <typename E>
|
||||
class EnumMask {
|
||||
public:
|
||||
uint64_t mBits = 0;
|
||||
|
||||
private:
|
||||
struct BitRef final {
|
||||
ExtensionBits& bits;
|
||||
EnumMask& bits;
|
||||
const uint64_t mask;
|
||||
|
||||
explicit operator bool() const { return bits.mBits & mask; }
|
||||
@ -555,15 +563,17 @@ class ExtensionBits final {
|
||||
}
|
||||
};
|
||||
|
||||
uint64_t Mask(const WebGLExtensionID i) const {
|
||||
uint64_t Mask(const E i) const {
|
||||
return uint64_t{1} << static_cast<uint64_t>(i);
|
||||
}
|
||||
|
||||
public:
|
||||
BitRef operator[](const WebGLExtensionID i) { return {*this, Mask(i)}; }
|
||||
bool operator[](const WebGLExtensionID i) const { return mBits & Mask(i); }
|
||||
BitRef operator[](const E i) { return {*this, Mask(i)}; }
|
||||
bool operator[](const E i) const { return mBits & Mask(i); }
|
||||
};
|
||||
|
||||
class ExtensionBits : public EnumMask<WebGLExtensionID> {};
|
||||
|
||||
// -
|
||||
|
||||
enum class ContextLossReason : uint8_t {
|
||||
@ -622,6 +632,7 @@ struct InitContextResult final {
|
||||
std::string error;
|
||||
WebGLContextOptions options;
|
||||
webgl::Limits limits;
|
||||
EnumMask<layers::SurfaceDescriptor::Type> uploadableSdTypes;
|
||||
};
|
||||
|
||||
// -
|
||||
@ -970,9 +981,8 @@ struct WebGLPixelStore final {
|
||||
void Apply(gl::GLContext&, bool isWebgl2, const uvec3& uploadSize) const;
|
||||
bool AssertCurrent(gl::GLContext&, bool isWebgl2) const;
|
||||
|
||||
WebGLPixelStore ForUseWith(
|
||||
const GLenum target, const uvec3& uploadSize,
|
||||
const Maybe<gfx::IntSize>& structuredSrcSize) const {
|
||||
WebGLPixelStore ForUseWith(const GLenum target, const uvec3& uploadSize,
|
||||
const Maybe<uvec2>& structuredSrcSize) const {
|
||||
auto ret = *this;
|
||||
|
||||
if (!IsTexTarget3D(target)) {
|
||||
@ -981,7 +991,7 @@ struct WebGLPixelStore final {
|
||||
}
|
||||
|
||||
if (structuredSrcSize) {
|
||||
ret.mUnpackRowLength = structuredSrcSize->width;
|
||||
ret.mUnpackRowLength = structuredSrcSize->x;
|
||||
}
|
||||
|
||||
if (!ret.mUnpackRowLength) {
|
||||
@ -1043,8 +1053,11 @@ struct TexUnpackBlobDesc final {
|
||||
|
||||
Maybe<RawBuffer<>> cpuData;
|
||||
Maybe<uint64_t> pboOffset;
|
||||
|
||||
uvec2 imageSize;
|
||||
RefPtr<layers::Image> image;
|
||||
RefPtr<gfx::DataSourceSurface> surf;
|
||||
Maybe<layers::SurfaceDescriptor> sd;
|
||||
RefPtr<gfx::DataSourceSurface> dataSurf;
|
||||
|
||||
WebGLPixelStore unpacking;
|
||||
|
||||
|
@ -221,6 +221,7 @@ if CONFIG["CC_TYPE"] in ("clang", "gcc"):
|
||||
|
||||
if CONFIG["CC_TYPE"] in ("clang", "clang-cl"):
|
||||
CXXFLAGS += ["-Werror=implicit-int-conversion"]
|
||||
CXXFLAGS += ["-Werror=switch"]
|
||||
|
||||
if CONFIG["CC_TYPE"] == "gcc":
|
||||
CXXFLAGS += ["-Wno-error=unused-result"] # GCC doesn't ignore (void)MustUse();
|
||||
|
@ -679,6 +679,41 @@ const DrawBlitProg* GLBlitHelper::CreateDrawBlitProg(
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
static RefPtr<MacIOSurface> LookupSurface(const layers::SurfaceDescriptorMacIOSurface& sd) {
|
||||
return MacIOSurface::LookupSurface(
|
||||
sd.surfaceId(), sd.scaleFactor(),
|
||||
!sd.isOpaque(), sd.yUVColorSpace());
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GLBlitHelper::BlitSdToFramebuffer(const layers::SurfaceDescriptor& asd,
|
||||
const gfx::IntSize& destSize,
|
||||
const OriginPos destOrigin) {
|
||||
const auto sdType = asd.type();
|
||||
switch (sdType) {
|
||||
#ifdef XP_WIN
|
||||
case layers::SurfaceDescriptor::TSurfaceDescriptorD3D10: {
|
||||
const auto& sd = asd.get_SurfaceDescriptorD3D10();
|
||||
return BlitDescriptor(sd, destSize, destOrigin);
|
||||
}
|
||||
case layers::SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr: {
|
||||
const auto& sd = asd.get_SurfaceDescriptorDXGIYCbCr();
|
||||
return BlitDescriptor(sd, destSize, destOrigin);
|
||||
}
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
case layers::SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
|
||||
const auto& sd = asd.get_SurfaceDescriptorMacIOSurface();
|
||||
const auto surf = LookupSurface(sd);
|
||||
return BlitImage(surf, destSize, destOrigin);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GLBlitHelper::BlitImageToFramebuffer(layers::Image* const srcImage,
|
||||
const gfx::IntSize& destSize,
|
||||
const OriginPos destOrigin) {
|
||||
|
@ -39,6 +39,7 @@ class GPUVideoImage;
|
||||
class PlanarYCbCrImage;
|
||||
class SurfaceTextureImage;
|
||||
class MacIOSurfaceImage;
|
||||
class SurfaceDescriptor;
|
||||
class SurfaceDescriptorD3D10;
|
||||
class SurfaceDescriptorDXGIYCbCr;
|
||||
} // namespace layers
|
||||
@ -194,6 +195,8 @@ class GLBlitHelper final {
|
||||
bool BlitImageToFramebuffer(layers::Image* srcImage,
|
||||
const gfx::IntSize& destSize,
|
||||
OriginPos destOrigin);
|
||||
bool BlitSdToFramebuffer(const layers::SurfaceDescriptor&,
|
||||
const gfx::IntSize& destSize, OriginPos destOrigin);
|
||||
|
||||
private:
|
||||
bool BlitImage(layers::GPUVideoImage* srcImage, const gfx::IntSize& destSize,
|
||||
|
@ -64,6 +64,8 @@ class D3D11ShareHandleImage final : public Image {
|
||||
TextureClient* GetTextureClient(KnowsCompositor* aKnowsCompositor) override;
|
||||
gfx::IntRect GetPictureRect() const override { return mPictureRect; }
|
||||
|
||||
Maybe<SurfaceDescriptor> GetDesc() override { return GetDescFromTexClient(); }
|
||||
|
||||
ID3D11Texture2D* GetTexture() const;
|
||||
|
||||
gfx::YUVColorSpace GetYUVColorSpace() const { return mYUVColorSpace; }
|
||||
|
@ -175,8 +175,6 @@ already_AddRefed<IDirect3DSurface9> D3D9SurfaceImage::GetD3D9Surface() const {
|
||||
return textureSurface.forget();
|
||||
}
|
||||
|
||||
const D3DSURFACE_DESC& D3D9SurfaceImage::GetDesc() const { return mDesc; }
|
||||
|
||||
HANDLE
|
||||
D3D9SurfaceImage::GetShareHandle() const { return mShareHandle; }
|
||||
|
||||
|
@ -93,8 +93,6 @@ class D3D9SurfaceImage : public Image {
|
||||
const gfx::IntRect& aRegion);
|
||||
|
||||
// Returns the description of the shared surface.
|
||||
const D3DSURFACE_DESC& GetDesc() const;
|
||||
|
||||
gfx::IntSize GetSize() const override;
|
||||
|
||||
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
||||
|
@ -56,6 +56,10 @@ class GPUVideoImage final : public Image {
|
||||
|
||||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
Maybe<SurfaceDescriptor> GetDesc() override {
|
||||
return GetDescFromTexClient(mTextureClient);
|
||||
}
|
||||
|
||||
private:
|
||||
GPUVideoTextureData* GetData() const {
|
||||
if (!mTextureClient) {
|
||||
|
@ -225,6 +225,24 @@ ImageContainer::~ImageContainer() {
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<SurfaceDescriptor> Image::GetDesc() { return {}; }
|
||||
|
||||
Maybe<SurfaceDescriptor> Image::GetDescFromTexClient(
|
||||
TextureClient* const forTc) {
|
||||
RefPtr<TextureClient> tc = forTc;
|
||||
if (!forTc) {
|
||||
tc = GetTextureClient(nullptr);
|
||||
}
|
||||
|
||||
const auto& tcd = tc->GetInternalData();
|
||||
|
||||
SurfaceDescriptor ret;
|
||||
if (!tcd->Serialize(ret)) {
|
||||
return {};
|
||||
}
|
||||
return Some(ret);
|
||||
}
|
||||
|
||||
RefPtr<PlanarYCbCrImage> ImageContainer::CreatePlanarYCbCrImage() {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
EnsureImageClient();
|
||||
|
@ -49,6 +49,7 @@ class ImageContainer;
|
||||
class ImageContainerChild;
|
||||
class SharedPlanarYCbCrImage;
|
||||
class SharedSurfacesAnimation;
|
||||
class SurfaceDescriptor;
|
||||
class PlanarYCbCrImage;
|
||||
class TextureClient;
|
||||
class TextureClientRecycleAllocator;
|
||||
@ -144,7 +145,12 @@ class Image {
|
||||
|
||||
virtual NVImage* AsNVImage() { return nullptr; }
|
||||
|
||||
virtual Maybe<SurfaceDescriptor> GetDesc();
|
||||
|
||||
protected:
|
||||
Maybe<SurfaceDescriptor> GetDescFromTexClient(
|
||||
TextureClient* tcOverride = nullptr);
|
||||
|
||||
Image(void* aImplData, ImageFormat aFormat)
|
||||
: mImplData(aImplData), mSerial(++sSerialCounter), mFormat(aFormat) {}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user