angle::Result ComputeStartVertex(ContextImpl *contextImpl, const gl::IndexRange &indexRange, GLint baseVertex, GLint *firstVertexOut) { // The entire index range should be within the limits of a 32-bit uint because the largest // GL index type is GL_UNSIGNED_INT. ASSERT(indexRange.start <= std::numeric_limits<uint32_t>::max() && indexRange.end <= std::numeric_limits<uint32_t>::max()); // The base vertex is only used in DrawElementsIndirect. Given the assertion above and the // type of mBaseVertex (GLint), adding them both as 64-bit ints is safe. int64_t startVertexInt64 = static_cast<int64_t>(baseVertex) + static_cast<int64_t>(indexRange.start); // OpenGL ES 3.2 spec section 10.5: "Behavior of DrawElementsOneInstance is undefined if the // vertex ID is negative for any element" ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 >= 0); // OpenGL ES 3.2 spec section 10.5: "If the vertex ID is larger than the maximum value // representable by type, it should behave as if the calculation were upconverted to 32-bit // unsigned integers(with wrapping on overflow conditions)." ANGLE does not fully handle // these rules, an overflow error is returned if the start vertex cannot be stored in a // 32-bit signed integer. ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 <= std::numeric_limits<GLint>::max()); *firstVertexOut = static_cast<GLint>(startVertexInt64); return angle::Result::Continue; }
angle::Result FramebufferD3D::readPixels(const gl::Context *context, const gl::Rectangle &area, GLenum format, GLenum type, void *pixels) { // Clip read area to framebuffer. const gl::Extents fbSize = getState().getReadAttachment()->getSize(); const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height); gl::Rectangle clippedArea; if (!ClipRectangle(area, fbRect, &clippedArea)) { // nothing to read return angle::Result::Continue; } const gl::PixelPackState &packState = context->getState().getPackState(); const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type); ContextD3D *contextD3D = GetImplAs<ContextD3D>(context); GLuint outputPitch = 0; ANGLE_CHECK_GL_MATH(contextD3D, sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength, &outputPitch)); GLuint outputSkipBytes = 0; ANGLE_CHECK_GL_MATH(contextD3D, sizedFormatInfo.computeSkipBytes( type, outputPitch, 0, packState, false, &outputSkipBytes)); outputSkipBytes += (clippedArea.x - area.x) * sizedFormatInfo.pixelBytes + (clippedArea.y - area.y) * outputPitch; return readPixelsImpl(context, clippedArea, format, type, outputPitch, packState, static_cast<uint8_t *>(pixels) + outputSkipBytes); }