Bug 1674592 - Shrink uploads based on byte size estimates. r=lsalzman

For example uploads from WASM heaps would previously copy most of the
heap into shmem.

Differential Revision: https://phabricator.services.mozilla.com/D96287
This commit is contained in:
Jeff Gilbert 2020-11-12 01:58:25 +00:00
Родитель 1f289c43a8
Коммит f7cb7a9dfc
3 изменённых файлов: 68 добавлений и 6 удалений

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

@ -3873,6 +3873,33 @@ Maybe<webgl::TexUnpackBlobDesc> FromDomElem(const ClientWebGLContext&,
ErrorResult* const out_error);
} // namespace webgl
void webgl::TexUnpackBlobDesc::Shrink(const webgl::PackingInfo& pi) {
if (cpuData) {
uint8_t bpp = 0;
if (!GetBytesPerPixel(pi, &bpp)) return;
MOZ_ASSERT(unpacking.mUnpackRowLength);
MOZ_ASSERT(unpacking.mUnpackAlignment);
const auto fullRowsNeeded = unpacking.FullRowsNeeded(size);
const auto bytesPerRowUnaligned =
CheckedInt<size_t>(unpacking.mUnpackRowLength) * bpp;
const auto bytesPerRowStride =
RoundUpToMultipleOf(bytesPerRowUnaligned, unpacking.mUnpackAlignment);
// Instead of trying to be careful about the last row, just use a foolproof
// upper-bound.
const auto totalRows =
fullRowsNeeded + 1; // fullRows + the last not-full row.
const auto bytesNeededUpperBound = totalRows * bytesPerRowStride;
if (bytesNeededUpperBound.isValid()) {
cpuData->Shrink(bytesNeededUpperBound.value());
}
return;
}
}
void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
GLint level, GLenum respecFormat,
const ivec3& offset, const ivec3& isize,
@ -4007,6 +4034,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
// -
desc->Shrink(pi);
Run<RPROC(TexImage)>(static_cast<uint32_t>(level), respecFormat,
CastUvec3(offset), pi, std::move(*desc));
}
@ -4014,7 +4042,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
GLenum imageTarget, GLint level,
GLenum format, const ivec3& offset,
const ivec3& size, GLint border,
const ivec3& isize, GLint border,
const TexImageSource& src,
GLsizei pboImageSize) const {
const FuncScope funcScope(*this, "compressedTex(Sub)Image[23]D");
@ -4045,9 +4073,12 @@ void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
MOZ_CRASH("impossible");
}
// We don't need to shrink `range` because valid calls require `range` to
// match requirements exactly.
Run<RPROC(CompressedTexImage)>(
sub, imageTarget, static_cast<uint32_t>(level), format, CastUvec3(offset),
CastUvec3(size), range, static_cast<uint32_t>(pboImageSize), pboOffset);
CastUvec3(isize), range, static_cast<uint32_t>(pboImageSize), pboOffset);
}
void ClientWebGLContext::CopyTexImage(uint8_t funcDims, GLenum imageTarget,

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

@ -74,10 +74,11 @@ static inline V* FindOrNull(const std::map<K, V*>& dest, const K2& key) {
}
// Returns a pointer to the in-place value for `key`.
template <typename K, typename V, typename K2>
static inline V* FindPtrOrNull(std::map<K, V>& dest, const K2& key) {
auto itr = dest.find(key);
if (itr == dest.end()) return nullptr;
template <typename C, typename K2>
static inline auto FindPtrOrNull(C& container, const K2& key) {
auto itr = container.find(key);
using R = decltype(&(itr->second));
if (itr == container.end()) return R{nullptr};
return &(itr->second);
}

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

@ -739,6 +739,11 @@ class RawBuffer final {
const auto& begin() const { return mBegin; }
const auto& size() const { return mLen; }
void Shrink(const size_t newLen) {
if (mLen <= newLen) return;
mLen = newLen;
}
RawBuffer() = default;
RawBuffer(const RawBuffer&) = delete;
@ -934,6 +939,29 @@ struct WebGLPixelStore final {
return ret;
}
CheckedInt<size_t> UsedPixelsPerRow(const uvec3& size) const {
if (!size.x || !size.y || !size.z) return 0;
return CheckedInt<size_t>(mUnpackSkipPixels) + size.x;
}
CheckedInt<size_t> FullRowsNeeded(const uvec3& size) const {
if (!size.x || !size.y || !size.z) return 0;
// The spec guarantees:
// * SKIP_PIXELS + width <= ROW_LENGTH.
// * SKIP_ROWS + height <= IMAGE_HEIGHT.
MOZ_ASSERT(mUnpackImageHeight);
auto skipFullRows =
CheckedInt<size_t>(mUnpackSkipImages) * mUnpackImageHeight;
skipFullRows += mUnpackSkipRows;
// Full rows in the final image, excluding the tail.
auto usedFullRows = CheckedInt<size_t>(size.z - 1) * mUnpackImageHeight;
usedFullRows += size.y - 1;
return skipFullRows + usedFullRows;
}
};
struct TexImageData final {
@ -960,6 +988,8 @@ struct TexUnpackBlobDesc final {
RefPtr<gfx::DataSourceSurface> surf;
WebGLPixelStore unpacking;
void Shrink(const webgl::PackingInfo&);
};
} // namespace webgl