Modified: trunk/Source/ThirdParty/ANGLE/ChangeLog (285219 => 285220)
--- trunk/Source/ThirdParty/ANGLE/ChangeLog 2021-11-03 20:09:01 UTC (rev 285219)
+++ trunk/Source/ThirdParty/ANGLE/ChangeLog 2021-11-03 20:10:21 UTC (rev 285220)
@@ -1,3 +1,21 @@
+2021-11-03 Kyle Piddington <kpidding...@apple.com>
+
+ REGRESSION (iOS 15): Tab crashes when trying to render Projector stories
+ https://bugs.webkit.org/show_bug.cgi?id=231607
+
+ Rework vertex buffer caching to allow us to reuse parts
+ of converted buffers. This dramatically drops the memory usage
+ of this tab from 4.5 gb to roughly 1.3gb
+
+ Reviewed by Dean Jackson.
+
+ * src/libANGLE/renderer/metal/BufferMtl.mm:
+ (rx::BufferMtl::getVertexConversionBuffer):
+ * src/libANGLE/renderer/metal/VertexArrayMtl.mm:
+ (rx::VertexArrayMtl::convertVertexBuffer):
+ (rx::VertexArrayMtl::convertVertexBufferCPU):
+ (rx::VertexArrayMtl::convertVertexBufferGPU):
+
2021-11-01 David Kilzer <ddkil...@apple.com>
[ANGLE] Enable -Wformat=2 warnings
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BufferMtl.mm (285219 => 285220)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BufferMtl.mm 2021-11-03 20:09:01 UTC (rev 285219)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BufferMtl.mm 2021-11-03 20:10:21 UTC (rev 285220)
@@ -333,7 +333,8 @@
{
for (VertexConversionBufferMtl &buffer : mVertexConversionBuffers)
{
- if (buffer.formatID == formatID && buffer.stride == stride && buffer.offset == offset)
+ if (buffer.formatID == formatID && buffer.stride == stride &&
+ buffer.offset <= offset && buffer.offset%buffer.stride == offset%stride)
{
return &buffer;
}
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/VertexArrayMtl.mm (285219 => 285220)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/VertexArrayMtl.mm 2021-11-03 20:09:01 UTC (rev 285219)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/VertexArrayMtl.mm 2021-11-03 20:10:21 UTC (rev 285220)
@@ -147,6 +147,30 @@
return numVertices;
}
+//Calculate how many vertices we intend to
+//convert, including any additional ones in the original conversion buffer
+size_t GetVertexCountWithConversion(BufferMtl *srcBuffer,
+ VertexConversionBufferMtl *conversionBuffer,
+ const gl::VertexBinding &binding,
+ uint32_t srcFormatSize)
+{
+ // Bytes usable for vertex data.
+ GLint64 bytes =
+ srcBuffer->size() - MIN((GLintptr)conversionBuffer->offset, binding.getOffset());
+ if (bytes < srcFormatSize)
+ return 0;
+
+ // Count the last vertex. It may occupy less than a full stride.
+ size_t numVertices = 1;
+ bytes -= srcFormatSize;
+
+ // Count how many strides fit remaining space.
+ if (bytes > 0)
+ numVertices += static_cast<size_t>(bytes) / binding.getStride();
+
+ return numVertices;
+}
+
inline size_t GetIndexCount(BufferMtl *srcBuffer, size_t offset, gl::DrawElementsType indexType)
{
size_t elementSize = gl::GetDrawElementsTypeSize(indexType);
@@ -966,8 +990,10 @@
// Has the content of the buffer has changed since last conversion?
if (!conversion->dirty)
{
+ VertexConversionBufferMtl * vertexConversionMtl = (VertexConversionBufferMtl *)conversion;
+ ASSERT((binding.getOffset() - vertexConversionMtl->offset) % stride == 0);
mConvertedArrayBufferHolders[attribIndex].set(conversion->convertedBuffer);
- mCurrentArrayBufferOffsets[attribIndex] = conversion->convertedOffset;
+ mCurrentArrayBufferOffsets[attribIndex] = conversion->convertedOffset + stride * ((binding.getOffset() - vertexConversionMtl->offset)/binding.getStride());
mCurrentArrayBuffers[attribIndex] = &mConvertedArrayBufferHolders[attribIndex];
mCurrentArrayBufferFormats[attribIndex] = &convertedFormat;
@@ -974,7 +1000,11 @@
mCurrentArrayBufferStrides[attribIndex] = stride;
return angle::Result::Continue;
}
-
+ // Update numVertices depending on where we intend to convert from.
+ // A new buffer compared to a reused one has a different
+ // starting offset.
+ numVertices = GetVertexCountWithConversion(srcBuffer, (VertexConversionBufferMtl *)conversion,
+ binding, srcFormatSize);
const angle::Format &convertedAngleFormat = convertedFormat.actualAngleFormat();
bool canConvertToFloatOnGPU =
convertedAngleFormat.isFloat() && !convertedAngleFormat.isVertexTypeHalfFloat();
@@ -1003,16 +1033,16 @@
ANGLE_TRY(convertVertexBufferCPU(contextMtl, srcBuffer, binding, attribIndex,
convertedFormat, stride, numVertices, conversion));
}
-
+ mConvertedArrayBufferHolders[attribIndex].set(conversion->convertedBuffer);
+ mCurrentArrayBufferOffsets[attribIndex] =
+ conversion->convertedOffset +
+ stride * ((binding.getOffset() - ((VertexConversionBufferMtl *)conversion)->offset) /
+ binding.getStride());
+ SimpleWeakBufferHolderMtl conversionBufferHolder;
mCurrentArrayBuffers[attribIndex] = &mConvertedArrayBufferHolders[attribIndex];
mCurrentArrayBufferFormats[attribIndex] = &convertedFormat;
mCurrentArrayBufferStrides[attribIndex] = stride;
-
- // Cache the last converted results to be re-used later if the buffer's content won't ever be
- // changed.
- conversion->convertedBuffer = mConvertedArrayBufferHolders[attribIndex].getCurrentBuffer();
- conversion->convertedOffset = mCurrentArrayBufferOffsets[attribIndex];
-
+
ASSERT(conversion->dirty);
conversion->dirty = false;
@@ -1040,14 +1070,15 @@
const uint8_t *srcBytes = srcBuffer->getClientShadowCopyData(contextMtl);
ANGLE_CHECK_GL_ALLOC(contextMtl, srcBytes);
-
- srcBytes += binding.getOffset();
-
+ //Copy the minimum between the binding offset and the conversion offset.
+ VertexConversionBufferMtl * vertexConversion = (VertexConversionBufferMtl *)conversion;
+ srcBytes += MIN(binding.getOffset(), vertexConversion->offset);
+ SimpleWeakBufferHolderMtl conversionBufferHolder;
ANGLE_TRY(StreamVertexData(
contextMtl, &conversion->data, srcBytes, numVertices * targetStride, 0, numVertices,
binding.getStride(), convertedFormat.vertexLoadFunction,
- &mConvertedArrayBufferHolders[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
-
+ &conversionBufferHolder, &conversion->convertedOffset));
+ conversion->convertedBuffer = conversionBufferHolder.getCurrentBuffer();
return angle::Result::Continue;
}
@@ -1073,9 +1104,9 @@
ANGLE_CHECK_GL_MATH(contextMtl, numVertices <= std::numeric_limits<uint32_t>::max());
mtl::VertexFormatConvertParams params;
-
+ VertexConversionBufferMtl * vertexConversion = (VertexConversionBufferMtl *)conversion;
params.srcBuffer = srcBuffer->getCurrentBuffer();
- params.srcBufferStartOffset = static_cast<uint32_t>(binding.getOffset());
+ params.srcBufferStartOffset = static_cast<uint32_t>(MIN(vertexConversion->offset,binding.getOffset()));
params.srcStride = binding.getStride();
params.srcDefaultAlphaData = convertedFormat.defaultAlpha;
@@ -1120,9 +1151,8 @@
ANGLE_TRY(conversion->data.commit(contextMtl));
- mConvertedArrayBufferHolders[attribIndex].set(newBuffer);
- mCurrentArrayBufferOffsets[attribIndex] = newBufferOffset;
-
+ conversion->convertedBuffer = newBuffer;
+ conversion->convertedOffset = newBufferOffset;
return angle::Result::Continue;
}
}