Moved global state into a class G
This allows other modules to do `from benchmark.space import G` and use the global state too. This is possible because the name `G` keeps referencing the same object (a class) even when resetting (contrary to the old `global_xxx = None`, which assigns a new object reference).
This commit is contained in:
@@ -30,19 +30,36 @@ COMPLETE_SCENES = ["barbershop_interior",
|
||||
"koro",
|
||||
"pavillon_barcelona"]
|
||||
|
||||
global_result_platform = None
|
||||
global_progress_status = None
|
||||
global_result_stats = None
|
||||
global_result_dict = None
|
||||
global_background_image_path = ""
|
||||
global_scene_status = {}
|
||||
global_cancel = False
|
||||
global_cached_system_info = None
|
||||
global_cached_compute_devices = None
|
||||
global_results_submitted = False
|
||||
images = {}
|
||||
current_progress = 0.0
|
||||
progress_lock = Lock()
|
||||
|
||||
class G:
|
||||
"""Global state of the Benchmark Client."""
|
||||
result_platform = None
|
||||
progress_status = None
|
||||
result_stats = None
|
||||
result_dict = None
|
||||
background_image_path = ""
|
||||
scene_status = {}
|
||||
cancel = False
|
||||
|
||||
cached_system_info = None
|
||||
cached_compute_devices = None
|
||||
results_submitted = False
|
||||
|
||||
images = {}
|
||||
current_progress = 0.0
|
||||
progress_lock = Lock()
|
||||
|
||||
@classmethod
|
||||
def reset(cls):
|
||||
"""Reset the global state."""
|
||||
cls.result_platform = None
|
||||
cls.progress_status = None
|
||||
cls.result_stats = None
|
||||
cls.result_dict = None
|
||||
cls.background_image_path = ""
|
||||
cls.scene_status = {}
|
||||
cls.results_submitted = False
|
||||
|
||||
|
||||
WELCOME_TEXT = "Run the Quick Benchmark on the selected device to\n" \
|
||||
"get a fast measurement of your hardware's performance.\n" \
|
||||
@@ -52,22 +69,6 @@ BLURB_TEXT = "Share your results with the world!\n" \
|
||||
"Manage the uploaded benchmark data on your Blender ID."
|
||||
|
||||
|
||||
def reset_global_state():
|
||||
global global_result_platform
|
||||
global global_progress_status
|
||||
global global_result_stats
|
||||
global global_result_dict
|
||||
global global_background_image_path
|
||||
global global_scene_status
|
||||
global global_results_submitted
|
||||
global_result_platform = None
|
||||
global_progress_status = None
|
||||
global_result_stats = None
|
||||
global_result_dict = None
|
||||
global_background_image_path = ""
|
||||
global_scene_status = {}
|
||||
global_results_submitted = False
|
||||
|
||||
################################################################################
|
||||
# Draw Utilities.
|
||||
|
||||
@@ -119,26 +120,23 @@ def draw_rect(x, y, w, h, color):
|
||||
|
||||
|
||||
def draw_image(filepath, x, y, w, h):
|
||||
global images
|
||||
if filepath not in images:
|
||||
if filepath not in G.images:
|
||||
ima = bpy.data.images.load(filepath)
|
||||
images[filepath] = ima
|
||||
|
||||
G.images[filepath] = ima
|
||||
import gpu
|
||||
gpu.draw.image(images[filepath], x, y, x + w, y + h)
|
||||
gpu.draw.image(G.images[filepath], x, y, x + w, y + h)
|
||||
|
||||
|
||||
################################################################################
|
||||
# Draw.
|
||||
|
||||
def benchmark_draw_post_pixel(arg1, arg2):
|
||||
global progress_lock
|
||||
progress_lock.acquire()
|
||||
progress_status = global_progress_status
|
||||
result_platform = global_result_platform
|
||||
result_stats = global_result_stats
|
||||
result_dict = global_result_dict
|
||||
progress_lock.release()
|
||||
G.progress_lock.acquire()
|
||||
progress_status = G.progress_status
|
||||
result_platform = G.result_platform
|
||||
result_stats = G.result_stats
|
||||
result_dict = G.result_dict
|
||||
G.progress_lock.release()
|
||||
|
||||
ui_scale = bpy.context.user_preferences.system.ui_scale
|
||||
blf.color(font_id, 1.0, 1.0, 1.0, 1.0)
|
||||
@@ -149,8 +147,8 @@ def benchmark_draw_post_pixel(arg1, arg2):
|
||||
image_h = 370 * ui_scale
|
||||
image_y = window_height - image_h
|
||||
|
||||
if global_background_image_path:
|
||||
draw_image(global_background_image_path, 0, image_y, window_width, image_h)
|
||||
if G.background_image_path:
|
||||
draw_image(G.background_image_path, 0, image_y, window_width, image_h)
|
||||
else:
|
||||
splash_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
splash_filepath = os.path.join(splash_dir, 'splash.png')
|
||||
@@ -161,7 +159,7 @@ def benchmark_draw_post_pixel(arg1, arg2):
|
||||
y = 0.70 * window_height
|
||||
|
||||
score = 0
|
||||
for name_stats in global_result_dict["scenes"]:
|
||||
for name_stats in G.result_dict["scenes"]:
|
||||
stat = name_stats['stats']
|
||||
if stat["result"] == "OK":
|
||||
score += stat["total_render_time"]
|
||||
@@ -198,16 +196,16 @@ def benchmark_draw_post_pixel(arg1, arg2):
|
||||
# Progress
|
||||
progress_x = 0.0
|
||||
progress_y = image_y + 1
|
||||
progress_w = window_width * current_progress
|
||||
progress_w = window_width * G.current_progress
|
||||
progress_h = 15.0 * ui_scale
|
||||
progress_color = [0.8, 1.0, 1.0, 0.2]
|
||||
|
||||
draw_rect(progress_x, progress_y, progress_w, progress_h, progress_color)
|
||||
|
||||
# Current status
|
||||
if global_progress_status:
|
||||
if G.progress_status:
|
||||
blf.size(font_id, int(18 * ui_scale), 72)
|
||||
draw_text_multiline(global_progress_status,
|
||||
draw_text_multiline(G.progress_status,
|
||||
progress_x + 8.0 * ui_scale,
|
||||
progress_y + progress_h + int(22 * ui_scale),
|
||||
shadow=True)
|
||||
@@ -274,49 +272,46 @@ class ProgressProviderSink:
|
||||
self.process = None
|
||||
|
||||
def progress(self, count, total, prefix="", suffix=""):
|
||||
progress_lock.acquire()
|
||||
G.progress_lock.acquire()
|
||||
if total != 0:
|
||||
self.current_progress = float(count) / float(total)
|
||||
else:
|
||||
self.current_progress = 0.0
|
||||
progress_lock.release()
|
||||
G.progress_lock.release()
|
||||
|
||||
def clear(self):
|
||||
progress_lock.acquire()
|
||||
G.progress_lock.acquire()
|
||||
self.current_progress = 0
|
||||
progress_lock.release()
|
||||
G.progress_lock.release()
|
||||
|
||||
def step(self, step_name):
|
||||
progress_lock.acquire()
|
||||
G.progress_lock.acquire()
|
||||
if self.current_step != step_name:
|
||||
self.current_step = step_name
|
||||
self.current_progress = 0
|
||||
progress_lock.release()
|
||||
G.progress_lock.release()
|
||||
|
||||
def scene(self, scene_name):
|
||||
progress_lock.acquire()
|
||||
G.progress_lock.acquire()
|
||||
self.current_scene = scene_name
|
||||
if scene_name:
|
||||
global global_scene_status
|
||||
global_scene_status[scene_name] = "Rendering..."
|
||||
progress_lock.release()
|
||||
G.scene_status[scene_name] = "Rendering..."
|
||||
G.progress_lock.release()
|
||||
|
||||
def scene_stats(self, scene_name, stats):
|
||||
progress_lock.acquire()
|
||||
global global_scene_status
|
||||
G.progress_lock.acquire()
|
||||
if stats:
|
||||
global_scene_status[scene_name] = util.humanReadableTimeDifference(
|
||||
G.scene_status[scene_name] = util.humanReadableTimeDifference(
|
||||
stats.total_render_time)
|
||||
else:
|
||||
global_scene_status[scene_name] = "Crashed :("
|
||||
progress_lock.release()
|
||||
G.scene_status[scene_name] = "Crashed :("
|
||||
G.progress_lock.release()
|
||||
|
||||
def render_process(self, process):
|
||||
self.process = process
|
||||
|
||||
def is_canceled(self):
|
||||
global global_cancel
|
||||
return global_cancel
|
||||
return G.cancel
|
||||
|
||||
|
||||
class LoggerProviderSink:
|
||||
@@ -455,15 +450,12 @@ def modify_device_info(device_info):
|
||||
|
||||
|
||||
def benchmark_thread(ctx):
|
||||
global progress_lock, global_result_platform, global_progress_status
|
||||
global global_cancel
|
||||
|
||||
progress_lock.acquire()
|
||||
global_progress_status = "Collecting system information."
|
||||
if global_cancel:
|
||||
progress_lock.release()
|
||||
G.progress_lock.acquire()
|
||||
G.progress_status = "Collecting system information."
|
||||
if G.cancel:
|
||||
G.progress_lock.release()
|
||||
return
|
||||
progress_lock.release()
|
||||
G.progress_lock.release()
|
||||
|
||||
blender_system_info = system_info_get(ctx)
|
||||
|
||||
@@ -474,13 +466,13 @@ def benchmark_thread(ctx):
|
||||
# TODO(sergey): Report an error somehow.
|
||||
return
|
||||
|
||||
progress_lock.acquire()
|
||||
global_result_platform = construct_platform_string(blender_system_info)
|
||||
if global_cancel:
|
||||
progress_lock.release()
|
||||
G.progress_lock.acquire()
|
||||
G.result_platform = construct_platform_string(blender_system_info)
|
||||
if G.cancel:
|
||||
G.progress_lock.release()
|
||||
return
|
||||
global_progress_status = "Prepating render."
|
||||
progress_lock.release()
|
||||
G.progress_status = "Prepating render."
|
||||
G.progress_lock.release()
|
||||
|
||||
all_stats = benchrunner.benchmarkAll(ctx)
|
||||
# Gather all information together.
|
||||
@@ -493,14 +485,13 @@ def benchmark_thread(ctx):
|
||||
"scenes": all_stats if all_stats else {}
|
||||
})
|
||||
|
||||
progress_lock.acquire()
|
||||
if global_cancel:
|
||||
progress_lock.release()
|
||||
G.progress_lock.acquire()
|
||||
if G.cancel:
|
||||
G.progress_lock.release()
|
||||
return
|
||||
progress_lock.release()
|
||||
G.progress_lock.release()
|
||||
|
||||
global global_result_dict
|
||||
global_result_dict = result
|
||||
G.result_dict = result
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -550,7 +541,7 @@ class BENCHMARK_PT_main(Panel):
|
||||
sub.separator()
|
||||
|
||||
compute_device_list_get(None, context)
|
||||
if len(global_cached_compute_devices) > 1:
|
||||
if len(G.cached_compute_devices) > 1:
|
||||
sub = col.row()
|
||||
sub.scale_y = 1.5
|
||||
sub.prop(context.scene, "compute_device", text="")
|
||||
@@ -587,7 +578,7 @@ class BENCHMARK_PT_main(Panel):
|
||||
sub.separator()
|
||||
|
||||
sub = col.row()
|
||||
sub.enabled = not global_results_submitted
|
||||
sub.enabled = not G.results_submitted
|
||||
sub.scale_y = 2.25
|
||||
sub.operator("benchmark.share", text="SHARE ONLINE")
|
||||
|
||||
@@ -606,13 +597,13 @@ class BENCHMARK_PT_main(Panel):
|
||||
|
||||
def draw(self, context):
|
||||
screen_index = 0
|
||||
global progress_lock
|
||||
progress_lock.acquire()
|
||||
if global_result_dict:
|
||||
|
||||
G.progress_lock.acquire()
|
||||
if G.result_dict:
|
||||
screen_index = 2
|
||||
elif global_result_stats or global_progress_status:
|
||||
elif G.result_stats or G.progress_status:
|
||||
screen_index = 1
|
||||
progress_lock.release()
|
||||
G.progress_lock.release()
|
||||
|
||||
if screen_index == 0:
|
||||
self.draw_welcome(context)
|
||||
@@ -673,39 +664,33 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
|
||||
logger.setProvider(self.logger_provider)
|
||||
|
||||
def update_status(self, context):
|
||||
global global_progress_status, global_background_image_path
|
||||
global global_cancel
|
||||
progress_lock.acquire()
|
||||
G.progress_lock.acquire()
|
||||
step = self.progress_provider.current_step
|
||||
if global_cancel:
|
||||
global_progress_status = "Canceling..."
|
||||
if G.cancel:
|
||||
G.progress_status = "Canceling..."
|
||||
elif step == 'WARM_UP':
|
||||
global_progress_status = "Rendering warm-up pass..."
|
||||
G.progress_status = "Rendering warm-up pass..."
|
||||
elif step == 'RUN':
|
||||
global current_progress
|
||||
current_progress = self.progress_provider.current_progress
|
||||
global_progress_status = "Rendering... Press Esc to stop."
|
||||
G.current_progress = self.progress_provider.current_progress
|
||||
G.progress_status = "Rendering... Press Esc to stop."
|
||||
context.area.tag_redraw()
|
||||
# Path to currently displayed background image.
|
||||
current_scene = self.progress_provider.current_scene
|
||||
if current_scene:
|
||||
global_background_image_path = os.path.join(
|
||||
G.background_image_path = os.path.join(
|
||||
self.benchmark_context.scenes_dir,
|
||||
current_scene,
|
||||
current_scene + ".png")
|
||||
else:
|
||||
global_background_image_path = ""
|
||||
G.background_image_path = ""
|
||||
# Update per-scene status string
|
||||
global global_result_stats
|
||||
global_result_stats = ""
|
||||
for scene in global_scene_status:
|
||||
global_result_stats += "{}: {}\n" . format(
|
||||
scene, global_scene_status[scene])
|
||||
progress_lock.release()
|
||||
G.result_stats = ""
|
||||
for scene in G.scene_status:
|
||||
G.result_stats += "{}: {}\n".format(
|
||||
scene, G.scene_status[scene])
|
||||
G.progress_lock.release()
|
||||
|
||||
def done(self, context):
|
||||
global global_progress_status, global_result_stats, current_progress
|
||||
global global_result_dict
|
||||
wm = context.window_manager
|
||||
wm.event_timer_remove(self.timer)
|
||||
# Restore all modifications to the benchmark foundation.
|
||||
@@ -717,30 +702,28 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
|
||||
self.progress_provider = None
|
||||
self.logger_provider = None
|
||||
# Construct final stats string
|
||||
if global_cancel:
|
||||
global_result_dict = None
|
||||
reset_global_state()
|
||||
elif global_result_dict:
|
||||
global_result_stats = ""
|
||||
for name_stat in global_result_dict["scenes"]:
|
||||
if G.cancel:
|
||||
G.reset()
|
||||
elif G.result_dict:
|
||||
G.result_stats = ""
|
||||
for name_stat in G.result_dict["scenes"]:
|
||||
stat = name_stat["stats"]
|
||||
if global_result_stats:
|
||||
global_result_stats += "\n"
|
||||
if G.result_stats:
|
||||
G.result_stats += "\n"
|
||||
if stat["result"] == "OK":
|
||||
global_result_stats += "{}: {}" . format(name_stat['name'],
|
||||
util.humanReadableTimeDifference(
|
||||
stat["total_render_time"]))
|
||||
G.result_stats += "{}: {}".format(name_stat['name'],
|
||||
util.humanReadableTimeDifference(
|
||||
stat["total_render_time"]))
|
||||
else:
|
||||
global_result_stats += "{}: {}" . format(name_stat['name'],
|
||||
stat["result"])
|
||||
G.result_stats += "{}: {}".format(name_stat['name'],
|
||||
stat["result"])
|
||||
else:
|
||||
global_result_stats = ""
|
||||
G.result_stats = ""
|
||||
# TOGO(sergey): Use some more nice picture for the final slide.
|
||||
global global_background_image_path
|
||||
global_background_image_path = ""
|
||||
G.background_image_path = ""
|
||||
# Tag for nice redraw
|
||||
global_progress_status = None
|
||||
current_progress = 0.0
|
||||
G.progress_status = None
|
||||
G.current_progress = 0.0
|
||||
context.area.tag_redraw()
|
||||
self.tmpdir = None
|
||||
|
||||
@@ -758,11 +741,9 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
global global_result_platform, global_progress_status
|
||||
global global_scene_status, global_cancel
|
||||
global_cancel = False
|
||||
global_result_platform = ""
|
||||
global_progress_status = "Initializing..."
|
||||
G.cancel = False
|
||||
G.result_platform = ""
|
||||
G.progress_status = "Initializing..."
|
||||
context.area.tag_redraw()
|
||||
|
||||
compute_device = context.scene.compute_device
|
||||
@@ -782,7 +763,7 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
|
||||
else:
|
||||
ctx.scenes = COMPLETE_SCENES
|
||||
for scene in ctx.scenes:
|
||||
global_scene_status[scene] = "Queued"
|
||||
G.scene_status[scene] = "Queued"
|
||||
ctx.scenes_dir = scenes_dir_get()
|
||||
ctx.device_type = device_type
|
||||
ctx.device_name = device_name
|
||||
@@ -806,11 +787,10 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def cancel_request(self, context):
|
||||
global global_cancel
|
||||
progress_lock.acquire()
|
||||
global_cancel = True
|
||||
G.progress_lock.acquire()
|
||||
G.cancel = True
|
||||
context.area.tag_redraw()
|
||||
progress_lock.release()
|
||||
G.progress_lock.release()
|
||||
if self.progress_provider.process:
|
||||
if platform.system() == "Windows":
|
||||
self.progress_provider.process.kill()
|
||||
@@ -819,7 +799,6 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
|
||||
self.progress_provider.process.send_signal(signal.SIGINT)
|
||||
|
||||
def cancel(self, context):
|
||||
global global_cancel
|
||||
self.cancel_request(context)
|
||||
if self.timer:
|
||||
wm = context.window_manager
|
||||
@@ -855,7 +834,7 @@ class BENCHMARK_OT_save(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
with open(self.filepath, "w") as f:
|
||||
f.write(json.dumps(global_result_dict, sort_keys=True, indent=2))
|
||||
f.write(json.dumps(G.result_dict, sort_keys=True, indent=2))
|
||||
make_buttons_green()
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -881,18 +860,17 @@ class BENCHMARK_OT_share(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
from benchmark import submission
|
||||
global global_results_submitted
|
||||
|
||||
make_buttons_default()
|
||||
print('Submitting benchmark')
|
||||
try:
|
||||
submission.submit_benchmark(global_result_dict)
|
||||
submission.submit_benchmark(G.result_dict)
|
||||
except Exception as ex:
|
||||
self.report({'ERROR'}, f'Error submitting results:\n{str(ex)[:100]}')
|
||||
return {'CANCELLED'}
|
||||
print('Submission done')
|
||||
make_buttons_green()
|
||||
global_results_submitted = True
|
||||
G.results_submitted = True
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@@ -913,7 +891,7 @@ class BENCHMARK_OT_restart(bpy.types.Operator):
|
||||
bl_label = "Go to a home screen and choose another benchmark to run"
|
||||
|
||||
def invoke(self, context, event):
|
||||
reset_global_state()
|
||||
G.reset()
|
||||
return {'FINISHED'}
|
||||
|
||||
################################################################################
|
||||
@@ -954,19 +932,17 @@ def find_first_device_index(compute_units, device_name):
|
||||
|
||||
|
||||
def compute_device_list_get(self, context):
|
||||
global global_cached_system_info
|
||||
global global_cached_compute_devices
|
||||
if global_cached_compute_devices:
|
||||
return global_cached_compute_devices
|
||||
if G.cached_compute_devices:
|
||||
return G.cached_compute_devices
|
||||
compute_devices = [('CPU:::', "CPU", "")]
|
||||
if not global_cached_system_info:
|
||||
if not G.cached_system_info:
|
||||
ctx = benchmark_context.Context()
|
||||
ctx.blender = blender_executable_get()
|
||||
ctx.configure_script = configure_script_get()
|
||||
global_cached_system_info = system_info_get(ctx)
|
||||
G.cached_system_info = system_info_get(ctx)
|
||||
compute_units = query_opencl_compute_units()
|
||||
device_indices = {}
|
||||
for device in global_cached_system_info["devices"]:
|
||||
for device in G.cached_system_info["devices"]:
|
||||
raw_device_name = device["name"]
|
||||
device_type = device["type"]
|
||||
if raw_device_name in device_indices:
|
||||
@@ -997,7 +973,7 @@ def compute_device_list_get(self, context):
|
||||
device["name"],
|
||||
device_index)
|
||||
compute_devices.append((device_id, device_name, ""))
|
||||
global_cached_compute_devices = compute_devices
|
||||
G.cached_compute_devices = compute_devices
|
||||
return compute_devices
|
||||
|
||||
################################################################################
|
||||
|
Reference in New Issue
Block a user