diff options
author | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2022-04-20 21:29:34 +0000 |
---|---|---|
committer | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2022-04-20 21:29:34 +0000 |
commit | 31d2958fd6426dc22f0664a582a754f00bbd4d5a (patch) | |
tree | 1b36178ad78456caf5cdf3d5b3b847f0bfb2ba83 | |
parent | 5b1f32fab8c59a091d0f08522f8f9f8ce284df79 (diff) | |
parent | c66de085aae15ae96b6959eb8651e4ffe2aec9b9 (diff) | |
download | angle-31d2958fd6426dc22f0664a582a754f00bbd4d5a.tar.gz |
Roll ANGLE from 3f800e5c8d68 to c66de085aae1 (5 revisions)
https://chromium.googlesource.com/angle/angle.git/+log/3f800e5c8d68..c66de085aae1
Please enable autosubmit on changes if possible when approving them.
If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/angle-android-autoroll
Please CC ianelliott@google.com on the revert to ensure that a human
is aware of the problem.
To file a bug in ANGLE: https://bugs.chromium.org/p/angleproject/issues/entry
To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug
Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Test: Presubmit checks will test this change.
Exempt-From-Owner-Approval: The autoroll bot does not require owner approval.
Bug: b/229689340
Change-Id: Ib86112faa89e07090eb1d49a28468a2dc1ff03ac
-rw-r--r-- | DEPS | 10 | ||||
-rw-r--r-- | scripts/code_generation_hashes/restricted_traces.json | 2 | ||||
-rw-r--r-- | src/libANGLE/State.cpp | 5 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/ContextVk.cpp | 14 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/ContextVk.h | 1 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/SurfaceVk.cpp | 43 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/TextureVk.cpp | 27 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/TextureVk.h | 26 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/vk_cache_utils.h | 6 | ||||
-rw-r--r-- | src/tests/angle_end2end_tests_expectations.txt | 4 | ||||
-rw-r--r-- | src/tests/gl_tests/TransformFeedbackTest.cpp | 35 | ||||
-rw-r--r-- | src/tests/py_utils/android_helper.py | 210 | ||||
-rw-r--r-- | src/tests/restricted_traces/BUILD.gn | 1 | ||||
-rwxr-xr-x | src/tests/restricted_traces/restricted_trace_gold_tests.py | 76 | ||||
-rw-r--r-- | src/tests/restricted_traces/restricted_traces.json | 1 |
15 files changed, 411 insertions, 50 deletions
@@ -1161,6 +1161,16 @@ deps = { 'dep_type': 'cipd', 'condition': 'checkout_angle_restricted_traces', }, + 'src/tests/restricted_traces/free_fire_max': { + 'packages': [ + { + 'package': 'angle/traces/free_fire_max', + 'version': 'version:1', + }, + ], + 'dep_type': 'cipd', + 'condition': 'checkout_angle_restricted_traces', + }, 'src/tests/restricted_traces/gardenscapes': { 'packages': [ { diff --git a/scripts/code_generation_hashes/restricted_traces.json b/scripts/code_generation_hashes/restricted_traces.json index 756ff7d7b4..bc7c4cf421 100644 --- a/scripts/code_generation_hashes/restricted_traces.json +++ b/scripts/code_generation_hashes/restricted_traces.json @@ -4,5 +4,5 @@ "src/tests/restricted_traces/gen_restricted_traces.py": "7780405f8e0d92fa87a772dd64c62efb", "src/tests/restricted_traces/restricted_traces.json": - "a14ef4e7bedcb42355134661e7cb5ebe" + "065d46b32f7d6e3381be2b524d748a2e" }
\ No newline at end of file diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp index 383bf7ce44..360896ce12 100644 --- a/src/libANGLE/State.cpp +++ b/src/libANGLE/State.cpp @@ -2176,10 +2176,7 @@ angle::Result State::detachBuffer(Context *context, const Buffer *buffer) if (curTransformFeedback) { ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID)); - if (isTransformFeedbackActiveUnpaused()) - { - context->getStateCache().onActiveTransformFeedbackChange(context); - } + context->getStateCache().onActiveTransformFeedbackChange(context); } if (getVertexArray()->detachBuffer(context, bufferID)) diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index 370512f9d5..cd37e36dec 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -3522,6 +3522,7 @@ angle::Result ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferH vk::ImageViewHelper *colorImageView, vk::ImageHelper *colorImage, vk::ImageHelper *colorImageMS, + VkPresentModeKHR presentMode, bool *imageResolved) { if (!mRenderPassCommands->started()) @@ -3574,10 +3575,15 @@ angle::Result ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferH onImageRenderPassWrite(gl::LevelIndex(0), 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment, colorImage); - const gl::Rectangle invalidateArea(0, 0, colorImageMS->getExtents().width, - colorImageMS->getExtents().height); - commandBufferHelper.invalidateRenderPassColorAttachment( - mState, 0, vk::PackedAttachmentIndex(0), invalidateArea); + // Invalidate the surface. See comment in WindowSurfaceVk::doDeferredAcquireNextImage on + // why this is not done when in DEMAND_REFRESH mode. + if (presentMode != VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR) + { + const gl::Rectangle invalidateArea(0, 0, colorImageMS->getExtents().width, + colorImageMS->getExtents().height); + commandBufferHelper.invalidateRenderPassColorAttachment( + mState, 0, vk::PackedAttachmentIndex(0), invalidateArea); + } ANGLE_TRY( flushCommandsAndEndRenderPass(RenderPassClosureReason::AlreadySpecifiedElsewhere)); diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h index f8f79b5591..d8f7840f02 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/src/libANGLE/renderer/vulkan/ContextVk.h @@ -447,6 +447,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText vk::ImageViewHelper *colorImageView, vk::ImageHelper *colorImage, vk::ImageHelper *colorImageMS, + VkPresentModeKHR presentMode, bool *imageResolved); vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType); diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp index be99b33fcf..a805efbe63 100644 --- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp +++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp @@ -1698,9 +1698,9 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk, bool imageResolved = false; if (currentFramebuffer.valid() && !overlayHasEnabledWidget(contextVk)) { - ANGLE_TRY(contextVk->optimizeRenderPassForPresent(currentFramebuffer.getHandle(), - &image.imageViews, &image.image, - &mColorImageMS, &imageResolved)); + ANGLE_TRY(contextVk->optimizeRenderPassForPresent( + currentFramebuffer.getHandle(), &image.imageViews, &image.image, &mColorImageMS, + mSwapchainPresentMode, &imageResolved)); } // Because the color attachment defers layout changes until endRenderPass time, we must call @@ -1909,21 +1909,34 @@ angle::Result WindowSurfaceVk::doDeferredAcquireNextImage(const gl::Context *con ANGLE_VK_TRY(contextVk, result); } - if (mState.swapBehavior == EGL_BUFFER_DESTROYED && mBufferAgeQueryFrameNumber == 0) + // Auto-invalidate the contents of the surface. According to EGL, on swap: + // + // - When EGL_BUFFER_DESTROYED is specified, the contents of the color image can be + // invalidated. + // * This is disabled with buffer age has been queried to work around a dEQP test bug. + // - Depth/Stencil can always be invalidated + // + // In all cases, when the present mode is DEMAND_REFRESH, swap is implicit and the swap behavior + // doesn't apply so no invalidation is done. + if (mSwapchainPresentMode != VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR) { - mSwapchainImages[mCurrentSwapchainImageIndex].image.invalidateSubresourceContent( - contextVk, gl::LevelIndex(0), 0, 1, nullptr); - if (mColorImageMS.valid()) + if (mState.swapBehavior == EGL_BUFFER_DESTROYED && mBufferAgeQueryFrameNumber == 0) { - mColorImageMS.invalidateSubresourceContent(contextVk, gl::LevelIndex(0), 0, 1, nullptr); + mSwapchainImages[mCurrentSwapchainImageIndex].image.invalidateSubresourceContent( + contextVk, gl::LevelIndex(0), 0, 1, nullptr); + if (mColorImageMS.valid()) + { + mColorImageMS.invalidateSubresourceContent(contextVk, gl::LevelIndex(0), 0, 1, + nullptr); + } + } + if (mDepthStencilImage.valid()) + { + mDepthStencilImage.invalidateSubresourceContent(contextVk, gl::LevelIndex(0), 0, 1, + nullptr); + mDepthStencilImage.invalidateSubresourceStencilContent(contextVk, gl::LevelIndex(0), 0, + 1, nullptr); } - } - if (mDepthStencilImage.valid()) - { - mDepthStencilImage.invalidateSubresourceContent(contextVk, gl::LevelIndex(0), 0, 1, - nullptr); - mDepthStencilImage.invalidateSubresourceStencilContent(contextVk, gl::LevelIndex(0), 0, 1, - nullptr); } return angle::Result::Continue; diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp index 6004027531..b650aa3c8a 100644 --- a/src/libANGLE/renderer/vulkan/TextureVk.cpp +++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp @@ -303,7 +303,9 @@ TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer) mImageCreateFlags(0), mImageObserverBinding(this, kTextureImageSubjectIndex), mCurrentBaseLevel(state.getBaseLevel()), - mCurrentMaxLevel(state.getMaxLevel()) + mCurrentMaxLevel(state.getMaxLevel()), + mCachedImageViewSubresourceSerialSRGBDecode{}, + mCachedImageViewSubresourceSerialSkipDecode{} {} TextureVk::~TextureVk() = default; @@ -2753,6 +2755,8 @@ angle::Result TextureVk::syncState(const gl::Context *context, &mImage->getYcbcrConversionDesc(), mImage->getIntendedFormatID()); ANGLE_TRY(renderer->getSamplerCache().getSampler(contextVk, samplerDesc, &mSampler)); + updateCachedImageViewSerials(); + return angle::Result::Continue; } @@ -3036,6 +3040,8 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk, levelCount, baseLayer, layerCount, createExtraSRGBViews, mImageUsageFlags & ~VK_IMAGE_USAGE_STORAGE_BIT, mState.getSamplerState())); + updateCachedImageViewSerials(); + return angle::Result::Continue; } @@ -3322,18 +3328,17 @@ void TextureVk::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMe onStateChange(message); } -vk::ImageOrBufferViewSubresourceSerial TextureVk::getImageViewSubresourceSerial( - const gl::SamplerState &samplerState) const +vk::ImageOrBufferViewSubresourceSerial TextureVk::getImageViewSubresourceSerialImpl( + GLenum srgbDecode) const { gl::LevelIndex baseLevel(mState.getEffectiveBaseLevel()); // getMipmapMaxLevel will clamp to the max level if it is smaller than the number of mips. uint32_t levelCount = gl::LevelIndex(mState.getMipmapMaxLevel()) - baseLevel + 1; - const angle::Format &angleFormat = mImage->getActualFormat(); - vk::SrgbDecodeMode srgbDecodeMode = - (angleFormat.isSRGB && (samplerState.getSRGBDecode() == GL_DECODE_EXT)) - ? vk::SrgbDecodeMode::SrgbDecode - : vk::SrgbDecodeMode::SkipDecode; + const angle::Format &angleFormat = mImage->getActualFormat(); + vk::SrgbDecodeMode srgbDecodeMode = (angleFormat.isSRGB && (srgbDecode == GL_DECODE_EXT)) + ? vk::SrgbDecodeMode::SrgbDecode + : vk::SrgbDecodeMode::SkipDecode; gl::SrgbOverride srgbOverrideMode = (!angleFormat.isSRGB && (mState.getSRGBOverride() == gl::SrgbOverride::SRGB)) ? gl::SrgbOverride::SRGB @@ -3503,4 +3508,10 @@ void TextureVk::stageSelfAsSubresourceUpdates(ContextVk *contextVk) mImage->stageSelfAsSubresourceUpdates(contextVk, mImage->getLevelCount(), mRedefinedLevels); } +void TextureVk::updateCachedImageViewSerials() +{ + mCachedImageViewSubresourceSerialSRGBDecode = getImageViewSubresourceSerialImpl(GL_DECODE_EXT); + mCachedImageViewSubresourceSerialSkipDecode = + getImageViewSubresourceSerialImpl(GL_SKIP_DECODE_EXT); +} } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/TextureVk.h b/src/libANGLE/renderer/vulkan/TextureVk.h index 829e5086d2..3d134226af 100644 --- a/src/libANGLE/renderer/vulkan/TextureVk.h +++ b/src/libANGLE/renderer/vulkan/TextureVk.h @@ -239,7 +239,22 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface angle::Result ensureImageInitialized(ContextVk *contextVk, ImageMipLevels mipLevels); vk::ImageOrBufferViewSubresourceSerial getImageViewSubresourceSerial( - const gl::SamplerState &samplerState) const; + const gl::SamplerState &samplerState) const + { + if (samplerState.getSRGBDecode() == GL_DECODE_EXT) + { + ASSERT(getImageViewSubresourceSerialImpl(GL_DECODE_EXT) == + mCachedImageViewSubresourceSerialSRGBDecode); + return mCachedImageViewSubresourceSerialSRGBDecode; + } + else + { + ASSERT(getImageViewSubresourceSerialImpl(GL_SKIP_DECODE_EXT) == + mCachedImageViewSubresourceSerialSkipDecode); + return mCachedImageViewSubresourceSerialSkipDecode; + } + } + vk::ImageOrBufferViewSubresourceSerial getBufferViewSerial() const; GLenum getColorReadFormat(const gl::Context *context) override; @@ -502,6 +517,11 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface void stageSelfAsSubresourceUpdates(ContextVk *contextVk); + vk::ImageOrBufferViewSubresourceSerial getImageViewSubresourceSerialImpl( + GLenum srgbDecode) const; + + void updateCachedImageViewSerials(); + bool mOwnsImage; bool mRequiresMutableStorage; vk::ImageAccess mRequiredImageAccess; @@ -584,6 +604,10 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface // Saved between updates. gl::LevelIndex mCurrentBaseLevel; gl::LevelIndex mCurrentMaxLevel; + + // Cached subresource indexes. + vk::ImageOrBufferViewSubresourceSerial mCachedImageViewSubresourceSerialSRGBDecode; + vk::ImageOrBufferViewSubresourceSerial mCachedImageViewSubresourceSerialSkipDecode; }; } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.h b/src/libANGLE/renderer/vulkan/vk_cache_utils.h index 7d32d38a7f..bc1955ac92 100644 --- a/src/libANGLE/renderer/vulkan/vk_cache_utils.h +++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.h @@ -1118,6 +1118,12 @@ struct ImageOrBufferViewSubresourceSerial ImageSubresourceRange subresource; }; +inline bool operator==(const ImageOrBufferViewSubresourceSerial &a, + const ImageOrBufferViewSubresourceSerial &b) +{ + return a.viewSerial == b.viewSerial && a.subresource == b.subresource; +} + constexpr ImageOrBufferViewSubresourceSerial kInvalidImageOrBufferViewSubresourceSerial = { kInvalidImageOrBufferViewSerial, kInvalidImageSubresourceRange}; diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt index 4d71bf69d5..ca4363adc3 100644 --- a/src/tests/angle_end2end_tests_expectations.txt +++ b/src/tests/angle_end2end_tests_expectations.txt @@ -593,3 +593,7 @@ // Flaking due to threading usage of the queue 7204 : VulkanImageTest.PreInitializedOnGLImport/ES3_Vulkan_SwiftShader_AsyncCommandQueue = SKIP + +// Causes incompatible error in GL back-end. +7218 OPENGL : TransformFeedbackTest.DrawAfterDeletingPausedBuffer/* = SKIP +7218 GLES : TransformFeedbackTest.DrawAfterDeletingPausedBuffer/* = SKIP diff --git a/src/tests/gl_tests/TransformFeedbackTest.cpp b/src/tests/gl_tests/TransformFeedbackTest.cpp index a4e4f86157..97b44f1fed 100644 --- a/src/tests/gl_tests/TransformFeedbackTest.cpp +++ b/src/tests/gl_tests/TransformFeedbackTest.cpp @@ -4105,6 +4105,41 @@ TEST_P(TransformFeedbackTest, ResumingTransformFeedbackAfterDeletebuffer) ASSERT_GL_ERROR(GL_INVALID_OPERATION); } +// Validates that drawing after deleting a buffer in a paused XFB. +TEST_P(TransformFeedbackTest, DrawAfterDeletingPausedBuffer) +{ + ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(testProgram, essl1_shaders::vs::Simple(), + essl1_shaders::fs::Green(), {"gl_Position"}, + GL_INTERLEAVED_ATTRIBS); + glUseProgram(testProgram); + + std::vector<uint8_t> data(100, 0); + + std::array<Vector3, 6> quadVerts = GetQuadVertices(); + + GLint loc = glGetAttribLocation(testProgram, essl1_shaders::PositionAttrib()); + ASSERT_NE(-1, loc); + + GLBuffer posBuf; + glBindBuffer(GL_ARRAY_BUFFER, posBuf); + glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + glEnableVertexAttribArray(loc); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLBuffer buf; + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, data.size() * sizeof(data[0]), data.data(), + GL_STATIC_DRAW); + glBeginTransformFeedback(GL_POINTS); + glPauseTransformFeedback(); + glDrawArrays(GL_POINTS, 0, 1); + buf.reset(); + glDrawArrays(GL_POINTS, 0, 1); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TransformFeedbackTest); ANGLE_INSTANTIATE_TEST_ES3(TransformFeedbackTest); diff --git a/src/tests/py_utils/android_helper.py b/src/tests/py_utils/android_helper.py new file mode 100644 index 0000000000..e3648c3a14 --- /dev/null +++ b/src/tests/py_utils/android_helper.py @@ -0,0 +1,210 @@ +# Copyright 2022 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import contextlib +import glob +import json +import logging +import os +import posixpath +import random +import subprocess +import tarfile +import tempfile +import time + +import angle_path_util + + +def _ApkPath(suite_name): + return os.path.join('%s_apk' % suite_name, '%s-debug.apk' % suite_name) + + +def ApkFileExists(suite_name): + return os.path.exists(_ApkPath(suite_name)) + + +def _Run(cmd): + logging.debug('Executing command: %s', cmd) + startupinfo = None + if hasattr(subprocess, 'STARTUPINFO'): + # Prevent console window popping up on Windows + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + output = subprocess.check_output(cmd, startupinfo=startupinfo) + return output + + +class Adb(object): + + def __init__(self, adb_path=None): + if not adb_path: + adb_path = os.path.join(angle_path_util.ANGLE_ROOT_DIR, + 'third_party/android_sdk/public/platform-tools/adb') + self._adb_path = adb_path + + def Run(self, args): + return _Run([self._adb_path] + args) + + def Shell(self, cmd): + return _Run([self._adb_path, 'shell', cmd]) + + +def _GetAdbRoot(adb): + adb.Run(['root']) + + for _ in range(20): + time.sleep(0.5) + try: + id_out = adb.Shell(adb_path, 'id').decode('ascii') + if 'uid=0(root)' in id_out: + return + except Exception: + continue + raise Exception("adb root failed") + + +def _ReadDeviceFile(adb, device_path): + out_wc = adb.Shell('cat %s | wc -c' % device_path) + expected_size = int(out_wc.decode('ascii').strip()) + out = adb.Run(['exec-out', 'cat %s' % device_path]) + assert len(out) == expected_size, 'exec-out mismatch' + return out + + +def _RemoveDeviceFile(adb, device_path): + adb.Shell('rm -f ' + device_path + ' || true') # ignore errors + + +def _AddRestrictedTracesJson(adb): + adb.Shell('mkdir -p /sdcard/chromium_tests_root/') + + def add(tar, fn): + assert (fn.startswith('../../')) + tar.add(fn, arcname=fn.replace('../../', '')) + + with _TempLocalFile() as tempfile_path: + with tarfile.open(tempfile_path, 'w', format=tarfile.GNU_FORMAT) as tar: + for f in glob.glob('../../src/tests/restricted_traces/*/*.json', recursive=True): + add(tar, f) + add(tar, '../../src/tests/restricted_traces/restricted_traces.json') + adb.Run(['push', tempfile_path, '/sdcard/chromium_tests_root/t.tar']) + + adb.Shell('r=/sdcard/chromium_tests_root; tar -xf $r/t.tar -C $r/ && rm $r/t.tar') + + +def PrepareTestSuite(adb, suite_name): + apk_path = _ApkPath(suite_name) + logging.info('Installing apk path=%s size=%s' % (apk_path, os.path.getsize(apk_path))) + + adb.Run(['install', '-r', '-d', apk_path]) + + permissions = [ + 'android.permission.CAMERA', 'android.permission.CHANGE_CONFIGURATION', + 'android.permission.READ_EXTERNAL_STORAGE', 'android.permission.RECORD_AUDIO', + 'android.permission.WRITE_EXTERNAL_STORAGE' + ] + adb.Shell('p=com.android.angle.test;' + 'for q in %s;do pm grant "$p" "$q";done;' % ' '.join(permissions)) + + if suite_name == 'angle_perftests': + _AddRestrictedTracesJson(adb) + + +def PrepareRestrictedTraces(adb, traces): + start = time.time() + total_size = 0 + for trace in traces: + path_from_root = 'src/tests/restricted_traces/' + trace + '/' + trace + '.angledata.gz' + local_path = '../../' + path_from_root + total_size += os.path.getsize(local_path) + adb.Run(['push', local_path, '/sdcard/chromium_tests_root/' + path_from_root]) + + logging.info('Pushed %d trace files (%.1fMB) in %.1fs', len(traces), total_size / 1e6, + time.time() - start) + + +def _RandomHex(): + return hex(random.randint(0, 2**64))[2:] + + +@contextlib.contextmanager +def _TempDeviceDir(adb): + path = '/sdcard/Download/temp_dir-%s' % _RandomHex() + adb.Shell('mkdir -p ' + path) + try: + yield path + finally: + adb.Shell('rm -rf ' + path) + + +@contextlib.contextmanager +def _TempDeviceFile(adb): + path = '/sdcard/Download/temp_file-%s' % _RandomHex() + try: + yield path + finally: + adb.Shell('rm -f ' + path) + + +@contextlib.contextmanager +def _TempLocalFile(): + fd, path = tempfile.mkstemp() + os.close(fd) + try: + yield path + finally: + os.remove(path) + + +def _RunInstrumentation(adb, flags): + with _TempDeviceFile(adb) as temp_device_file: + cmd = ' '.join([ + 'p=com.android.angle.test;', + 'ntr=org.chromium.native_test.NativeTestInstrumentationTestRunner;', + 'am instrument -w', + '-e $ntr.NativeTestActivity "$p".AngleUnitTestActivity', + '-e $ntr.ShardNanoTimeout 2400000000000', + '-e org.chromium.native_test.NativeTest.CommandLineFlags "%s"' % ' '.join(flags), + '-e $ntr.StdoutFile ' + temp_device_file, + '"$p"/org.chromium.build.gtest_apk.NativeTestInstrumentationTestRunner', + ]) + + adb.Shell(cmd) + return _ReadDeviceFile(adb, temp_device_file) + + +def AngleSystemInfo(adb, args): + PrepareTestSuite(adb, 'angle_system_info_test') + + with _TempDeviceDir(adb) as temp_dir: + _RunInstrumentation(adb, args + ['--render-test-output-dir=' + temp_dir]) + output_file = posixpath.join(temp_dir, 'angle_system_info.json') + return json.loads(_ReadDeviceFile(adb, output_file)) + + +def ListTests(adb): + out_lines = _RunInstrumentation(adb, ["--list-tests"]).decode('ascii').split('\n') + + start = out_lines.index('Tests list:') + end = out_lines.index('End tests list.') + return out_lines[start + 1:end] + + +def _PullDir(adb, device_dir, local_dir): + files = adb.Shell('ls -1 %s' % device_dir).decode('ascii').split('\n') + for f in files: + f = f.strip() + if f: + adb.Run(['pull', posixpath.join(device_dir, f), posixpath.join(local_dir, f)]) + + +def RunTests(adb, test_suite, args, stdoutfile, output_dir): + with _TempDeviceDir(adb) as temp_dir: + output = _RunInstrumentation(adb, args + ['--render-test-output-dir=' + temp_dir]) + with open(stdoutfile, 'wb') as f: + f.write(output) + logging.info(output.decode()) + _PullDir(adb, temp_dir, output_dir) diff --git a/src/tests/restricted_traces/BUILD.gn b/src/tests/restricted_traces/BUILD.gn index 1108deb607..320addff0f 100644 --- a/src/tests/restricted_traces/BUILD.gn +++ b/src/tests/restricted_traces/BUILD.gn @@ -78,6 +78,7 @@ group("angle_restricted_trace_gold_tests") { data = [ "restricted_trace_gold_tests.py", "restricted_traces.json", + "../py_utils/android_helper.py", "../py_utils/angle_path_util.py", "../py_utils/skia_gold/", "//build/skia_gold_common/", diff --git a/src/tests/restricted_traces/restricted_trace_gold_tests.py b/src/tests/restricted_traces/restricted_trace_gold_tests.py index c19c7d0b4f..2708f5e339 100755 --- a/src/tests/restricted_traces/restricted_trace_gold_tests.py +++ b/src/tests/restricted_traces/restricted_trace_gold_tests.py @@ -30,6 +30,7 @@ def _AddToPathIfNeeded(path): _AddToPathIfNeeded(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'py_utils'))) +import android_helper import angle_path_util from skia_gold import angle_skia_gold_properties from skia_gold import angle_skia_gold_session_manager @@ -120,11 +121,43 @@ def add_skia_gold_args(parser): 'pre-authenticated. Meant for testing locally instead of on the bots.') -def run_wrapper(args, cmd, env, stdoutfile=None): +def _adb_if_android(args): + if android_helper.ApkFileExists(args.test_suite): + return android_helper.Adb() + + return None + + +def run_wrapper(test_suite, cmd_args, args, env, stdoutfile, output_dir=None): + cmd = [get_binary_name(test_suite)] + cmd_args + if output_dir: + cmd += ['--render-test-output-dir=%s' % output_dir] + if args.xvfb: return xvfb.run_executable(cmd, env, stdoutfile=stdoutfile) else: - return test_env.run_command_with_output(cmd, env=env, stdoutfile=stdoutfile) + adb = _adb_if_android(args) + if adb: + try: + android_helper.RunTests(adb, test_suite, cmd_args, stdoutfile, output_dir) + return 0 + except Exception as e: + logging.exception(e) + return 1 + else: + return test_env.run_command_with_output(cmd, env=env, stdoutfile=stdoutfile) + + +def run_angle_system_info_test(sysinfo_args, args, env): + with temporary_dir() as temp_dir: + tempfile_path = os.path.join(temp_dir, 'stdout') + sysinfo_args += ['--render-test-output-dir=' + temp_dir] + + if run_wrapper('angle_system_info_test', sysinfo_args, args, env, tempfile_path): + raise Exception('Error getting system info.') + + with open(os.path.join(temp_dir, 'angle_system_info.json')) as f: + return json.load(f) def to_hex(num): @@ -159,17 +192,16 @@ def get_skia_gold_keys(args, env): logging.exception('get_skia_gold_keys may only be called once') get_skia_gold_keys.called = True - with temporary_dir() as temp_dir: - binary = get_binary_name('angle_system_info_test') - sysinfo_args = [binary, '--vulkan', '-v', '--render-test-output-dir=' + temp_dir] - if args.swiftshader: - sysinfo_args.append('--swiftshader') - tempfile_path = os.path.join(temp_dir, 'stdout') - if run_wrapper(args, sysinfo_args, env, tempfile_path): - raise Exception('Error getting system info.') + sysinfo_args = ['--vulkan', '-v'] + if args.swiftshader: + sysinfo_args.append('--swiftshader') - with open(os.path.join(temp_dir, 'angle_system_info.json')) as f: - json_data = json.load(f) + adb = _adb_if_android(args) + if adb: + json_data = android_helper.AngleSystemInfo(adb, sysinfo_args) + logging.info(json_data) + else: + json_data = run_angle_system_info_test(sysinfo_args, args, env) if len(json_data.get('gpus', [])) == 0 or not 'activeGPUIndex' in json_data: raise Exception('Error getting system info.') @@ -291,6 +323,10 @@ def _get_gtest_filter_for_batch(args, batch): def _run_tests(args, tests, extra_flags, env, screenshot_dir, results, test_results): keys = get_skia_gold_keys(args, env) + adb = _adb_if_android(args) + if adb: + android_helper.PrepareTestSuite(adb, args.test_suite) + with temporary_dir('angle_skia_gold_') as skia_gold_temp_dir: gold_properties = angle_skia_gold_properties.ANGLESkiaGoldProperties(args) gold_session_manager = angle_skia_gold_session_manager.ANGLESkiaGoldSessionManager( @@ -314,6 +350,9 @@ def _run_tests(args, tests, extra_flags, env, screenshot_dir, results, test_resu batches = _get_batches(traces, args.batch_size) for batch in batches: + if adb: + android_helper.PrepareRestrictedTraces(adb, batch) + for iteration in range(0, args.flaky_retries + 1): with common.temporary_file() as tempfile_path: # This is how we signal early exit @@ -324,16 +363,19 @@ def _run_tests(args, tests, extra_flags, env, screenshot_dir, results, test_resu logging.info('Test run failed, running retry #%d...' % iteration) gtest_filter = _get_gtest_filter_for_batch(args, batch) - cmd = [ - get_binary_name(args.test_suite), + cmd_args = [ gtest_filter, - '--render-test-output-dir=%s' % screenshot_dir, '--one-frame-only', '--verbose-logging', '--enable-all-trace-tests', ] + extra_flags - batch_result = PASS if run_wrapper(args, cmd, env, - tempfile_path) == 0 else FAIL + batch_result = PASS if run_wrapper( + args.test_suite, + cmd_args, + args, + env, + tempfile_path, + output_dir=screenshot_dir) == 0 else FAIL with open(tempfile_path) as f: test_output = f.read() + '\n' diff --git a/src/tests/restricted_traces/restricted_traces.json b/src/tests/restricted_traces/restricted_traces.json index 9dfda67edb..695bdb9258 100644 --- a/src/tests/restricted_traces/restricted_traces.json +++ b/src/tests/restricted_traces/restricted_traces.json @@ -59,6 +59,7 @@ "fire_emblem_heroes 1", "five_nights_at_freddys 1", "free_fire 5", + "free_fire_max 1", "gardenscapes 5", "genshin_impact 5", "google_maps 5", |