1515 CursorShape ,
1616 CursorShapeEnum ,
1717)
18+ from . import contexts
1819from ._events import EventEmitter
1920from ._loop import BaseLoop
2021from ._scheduler import Scheduler
@@ -238,12 +239,14 @@ def get_context(self, context_type: str) -> object:
238239 if not isinstance (context_type , str ):
239240 raise TypeError ("context_type must be str." )
240241
242+ present_method_map = context_type_map = {"screen" : "wgpu" }
243+
241244 # Resolve the context type name
242- known_types = {
243- "wgpu" : "wgpu" ,
244- "bitmap" : "rendercanvas.utils.bitmaprenderingcontext" ,
245- }
246- resolved_context_type = known_types . get ( context_type , context_type )
245+ resolved_context_type = context_type_map . get ( context_type , context_type )
246+ if resolved_context_type not in ( "bitmap" , "wgpu" ):
247+ raise ValueError (
248+ "The given context type is invalid: {context_type!r} is not 'bitmap' or 'wgpu'."
249+ )
247250
248251 # Is the context already set?
249252 if self ._canvas_context is not None :
@@ -254,34 +257,70 @@ def get_context(self, context_type: str) -> object:
254257 f"Cannot get context for '{ context_type } ': a context of type '{ self ._canvas_context ._context_type } ' is already set."
255258 )
256259
257- # Load module
258- module_name , _ , class_name = resolved_context_type .partition (":" )
259- try :
260- module = importlib .import_module (module_name )
261- except ImportError as err :
262- raise ValueError (
263- f"Cannot get context for '{ context_type } ': { err } . Known valid values are { set (known_types )} "
264- ) from None
265-
266- # Obtain factory to produce context
267- factory_name = class_name or "rendercanvas_context_hook"
268- try :
269- factory_func = getattr (module , factory_name )
270- except AttributeError :
271- raise ValueError (
272- f"Cannot get context for '{ context_type } ': could not find `{ factory_name } ` in '{ module .__name__ } '"
273- ) from None
274-
275- # Create the context
276- context = factory_func (self , self ._rc_get_present_methods ())
260+ # # Load module
261+ # module_name, _, class_name = resolved_context_type.partition(":")
262+ # try:
263+ # module = importlib.import_module(module_name)
264+ # except ImportError as err:
265+ # raise ValueError(
266+ # f"Cannot get context for '{context_type}': {err}. Known valid values are {set(known_types)}"
267+ # ) from None
268+
269+ # # Obtain factory to produce context
270+ # factory_name = class_name or "rendercanvas_context_hook"
271+ # try:
272+ # factory_func = getattr(module, factory_name)
273+ # except AttributeError:
274+ # raise ValueError(
275+ # f"Cannot get context for '{context_type}': could not find `{factory_name}` in '{module.__name__}'"
276+ # ) from None
277+
278+ # # Create the context
279+ # context = factory_func(self, self._rc_get_present_methods())
280+
281+ # # Quick checks to make sure the context has the correct API
282+ # if not (hasattr(context, "canvas") and context.canvas is self):
283+ # raise RuntimeError(
284+ # "The context does not have a canvas attribute that refers to this canvas."
285+ # )
286+ # if not (hasattr(context, "present") and callable(context.present)):
287+ # raise RuntimeError("The context does not have a present method.")
288+
289+ # Select present_method
290+ # todo: does the canvas present_method arg override this in the appropriate way?
291+ present_methods = self ._rc_get_present_methods ()
292+ present_method = None
293+ if resolved_context_type == "bitmap" :
294+ for name in ("bitmap" , "wgpu" , "screen" ):
295+ if name in present_methods :
296+ present_method = name
297+ break
298+ else :
299+ for name in ("wgpu" , "screen" , "bitmap" ):
300+ if name in present_methods :
301+ present_method = name
302+ break
277303
278- # Quick checks to make sure the context has the correct API
279- if not ( hasattr ( context , "canvas" ) and context . canvas is self ) :
304+ # This should never happen, unless there's a bug
305+ if present_method is None :
280306 raise RuntimeError (
281- "The context does not have a canvas attribute that refers to this canvas. "
307+ "Could not select present_method for context_type {context_type!r} from present_methods {present_methods!r} "
282308 )
283- if not (hasattr (context , "present" ) and callable (context .present )):
284- raise RuntimeError ("The context does not have a present method." )
309+
310+ # Select present_info
311+ present_info = dict (present_methods [present_method ])
312+ assert "method" not in present_info , (
313+ "the field 'method' is reserved in present_methods dicts"
314+ )
315+ present_info = {
316+ "method" : present_method_map .get (present_method , present_method ),
317+ ** present_info ,
318+ }
319+
320+ if resolved_context_type == "bitmap" :
321+ context = contexts .BitmapContext (self , present_info )
322+ else :
323+ context = contexts .WGpuContext (self , present_info )
285324
286325 # Done
287326 self ._canvas_context = context
@@ -498,9 +537,9 @@ def _draw_frame_and_present(self):
498537 # Note: if vsync is used, this call may wait a little (happens down at the level of the driver or OS)
499538 context = self ._canvas_context
500539 if context :
501- result = context .present ()
540+ result = context ._rc_present ()
502541 method = result .pop ("method" )
503- if method in ("skip" , "screen" ):
542+ if method in ("skip" , "screen" , "delegated" ):
504543 pass # nothing we need to do
505544 elif method == "fail" :
506545 raise RuntimeError (result .get ("message" , "" ) or "present error" )
0 commit comments