# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from telemetry import test from telemetry.page import page_test MEMORY_LIMIT_MB = 256 SINGLE_TAB_LIMIT_MB = 128 WIGGLE_ROOM_MB = 4 test_harness_script = r""" var domAutomationController = {}; domAutomationController._finished = false; domAutomationController.send = function(msg) { // This should wait until all effects of memory management complete. // We will need to wait until all // 1. pending commits from the main thread to the impl thread in the // compositor complete (for visible compositors). // 2. allocations that the renderer's impl thread will make due to the // compositor and WebGL are completed. // 3. pending GpuMemoryManager::Manage() calls to manage are made. // 4. renderers' OnMemoryAllocationChanged callbacks in response to // manager are made. // Each step in this sequence can cause trigger the next (as a 1-2-3-4-1 // cycle), so we will need to pump this cycle until it stabilizes. // Pump the cycle 8 times (in principle it could take an infinite number // of iterations to settle). var rafCount = 0; var totalRafCount = 8; function pumpRAF() { if (rafCount == totalRafCount) { domAutomationController._finished = true; return; } ++rafCount; window.requestAnimationFrame(pumpRAF); } pumpRAF(); } window.domAutomationController = domAutomationController; window.addEventListener("load", function() { useGpuMemory(%d); }, false); """ % MEMORY_LIMIT_MB class MemoryValidator(page_test.PageTest): def __init__(self): super(MemoryValidator, self).__init__('ValidatePage') def ValidatePage(self, page, tab, results): mb_used = MemoryValidator.GpuMemoryUsageMbytes(tab) if mb_used + WIGGLE_ROOM_MB < SINGLE_TAB_LIMIT_MB: raise page_test.Failure('Memory allocation too low') if mb_used - WIGGLE_ROOM_MB > MEMORY_LIMIT_MB: raise page_test.Failure('Memory allocation too high') @staticmethod def GpuMemoryUsageMbytes(tab): gpu_rendering_stats_js = 'chrome.gpuBenchmarking.gpuRenderingStats()' gpu_rendering_stats = tab.EvaluateJavaScript(gpu_rendering_stats_js) return gpu_rendering_stats['globalVideoMemoryBytesAllocated'] / 1048576 def CustomizeBrowserOptions(self, options): options.AppendExtraBrowserArgs('--enable-logging') options.AppendExtraBrowserArgs( '--force-gpu-mem-available-mb=%s' % MEMORY_LIMIT_MB) options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') class Memory(test.Test): """Tests GPU memory limits""" test = MemoryValidator page_set = 'page_sets/memory_tests.json' def CreatePageSet(self, options): page_set = super(Memory, self).CreatePageSet(options) for page in page_set.pages: page.script_to_evaluate_on_commit = test_harness_script return page_set