aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com>2022-04-21 06:40:26 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-04-21 06:40:26 +0000
commita61ef3fe970fd40b6f9a2842c46d603672e7e195 (patch)
tree1b36178ad78456caf5cdf3d5b3b847f0bfb2ba83
parent0bed77c9cd03e237254bab3c421c999d5ed5cc7c (diff)
parent31d2958fd6426dc22f0664a582a754f00bbd4d5a (diff)
downloadangle-a61ef3fe970fd40b6f9a2842c46d603672e7e195.tar.gz
Roll ANGLE from 3f800e5c8d68 to c66de085aae1 (5 revisions) am: 31d2958fd6
Original change: https://android-review.googlesource.com/c/platform/external/angle/+/2069909 Change-Id: I389607bada1817c15cdad5a61039dee2fb45c9f3 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--DEPS10
-rw-r--r--scripts/code_generation_hashes/restricted_traces.json2
-rw-r--r--src/libANGLE/State.cpp5
-rw-r--r--src/libANGLE/renderer/vulkan/ContextVk.cpp14
-rw-r--r--src/libANGLE/renderer/vulkan/ContextVk.h1
-rw-r--r--src/libANGLE/renderer/vulkan/SurfaceVk.cpp43
-rw-r--r--src/libANGLE/renderer/vulkan/TextureVk.cpp27
-rw-r--r--src/libANGLE/renderer/vulkan/TextureVk.h26
-rw-r--r--src/libANGLE/renderer/vulkan/vk_cache_utils.h6
-rw-r--r--src/tests/angle_end2end_tests_expectations.txt4
-rw-r--r--src/tests/gl_tests/TransformFeedbackTest.cpp35
-rw-r--r--src/tests/py_utils/android_helper.py210
-rw-r--r--src/tests/restricted_traces/BUILD.gn1
-rwxr-xr-xsrc/tests/restricted_traces/restricted_trace_gold_tests.py76
-rw-r--r--src/tests/restricted_traces/restricted_traces.json1
15 files changed, 411 insertions, 50 deletions
diff --git a/DEPS b/DEPS
index ddcbf643a5..5f8d44af6c 100644
--- a/DEPS
+++ b/DEPS
@@ -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",