Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ jobs:
"
pytest -v tests

test-examples-build:
test-examples:
name: Test examples ${{ matrix.pyversion }}
runs-on: ${{ matrix.os }}
strategy:
Expand Down Expand Up @@ -183,8 +183,8 @@ jobs:
pushd $HOME
pytest -v --pyargs rendercanvas.__pyinstaller

release:
name: Build release on ubuntu-latest
build-release:
name: Build release artifacts
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -227,7 +227,7 @@ jobs:
publish:
name: Publish release to Github and Pypi
runs-on: ubuntu-latest
needs: [tests, release]
needs: [tests, build-release]
if: success() && startsWith(github.ref, 'refs/tags/v')
environment:
name: pypi
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import numpy as np
from rendercanvas.auto import RenderCanvas, loop

canvas = RenderCanvas(update_mode="continuous")
context = canvas.get_context("bitmap")
context = canvas.get_bitmap_context()

@canvas.request_draw
def animate():
Expand Down
4 changes: 2 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
API
===
Canvas API
==========

These are the classes that make up the rendercanvas API:

Expand Down
3 changes: 1 addition & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
# Load wgpu so autodoc can query docstrings
import rendercanvas # noqa: E402
import rendercanvas.stub # noqa: E402 - we use the stub backend to generate docs
import rendercanvas._context # noqa: E402 - we use the ContextInterface to generate docs
import rendercanvas.utils.bitmappresentadapter # noqa: E402


# -- Project information -----------------------------------------------------

Expand Down
66 changes: 11 additions & 55 deletions docs/contextapi.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
How context objects work
========================

This page documents the working bentween the ``RenderCanvas`` and the context object.
This page documents the inner working between the ``RenderCanvas`` and the context object.


Introduction
Expand All @@ -23,16 +23,13 @@ then present the result to the screen. For this, the canvas provides one or more
│ │ ──bitmap──► │ │
└─────────┘ └────────┘

This means that for the context to be able to present to any canvas, it must
support *both* the 'bitmap' and 'screen' present-methods. If the context prefers
presenting to the screen, and the canvas supports that, all is well. Similarly,
if the context has a bitmap to present, and the canvas supports the
bitmap-method, there's no problem.
If the context is a ``BitmapContext``, and the canvas supports the bitmap present-method,
things are easy. Similarly, if the context is a ``WgpuContext``, and the canvas
supports the screen present-method, the presenting is simply delegated to wgpu.

It get's a little trickier when there's a mismatch, but we can deal with these
cases too. When the context prefers presenting to screen, the rendered result is
probably a texture on the GPU. This texture must then be downloaded to a bitmap
on the CPU. All GPU API's have ways to do this.
When there's a mismatch, we use different context sub-classes that handle the conversion.
With the ``WgpuContextToBitmap`` context, the rendered result is inside a texture on the GPU.
This texture is then downloaded to a bitmap on the CPU that can be passed to the canvas.

.. code-block::

Expand All @@ -41,11 +38,10 @@ on the CPU. All GPU API's have ways to do this.
──render──► | Context │ | │ Canvas │
│ │ └─bitmap──► │ |
└─────────┘ └────────┘
download from gpu to cpu
download to CPU

If the context has a bitmap to present, and the canvas only supports presenting
to screen, you can use a small utility: the ``BitmapPresentAdapter`` takes a
bitmap and presents it to the screen.
With the ``BitmapContextToScreen`` context, the bitmap is uploaded to a GPU texture,
which is then rendered to screen using the lower-level canvas-context from ``wgpu``.

.. code-block::

Expand All @@ -54,46 +50,6 @@ bitmap and presents it to the screen.
──render──► | Context │ │ │ Canvas │
│ │ ──bitmap─┘ │ |
└─────────┘ └────────┘
use BitmapPresentAdapter
upload to GPU

This way, contexts can be made to work with all canvas backens.

Canvases may also provide additionally present-methods. If a context knows how to
use that present-method, it can make use of it. Examples could be presenting
diff images or video streams.

.. code-block::

┌─────────┐ ┌────────┐
│ │ │ │
──render──► | Context │ ──special-present-method──► │ Canvas │
│ │ │ |
└─────────┘ └────────┘


Context detection
-----------------

Anyone can make a context that works with ``rendercanvas``. In order for ``rendercanvas`` to find, it needs a little hook.

.. autofunction:: rendercanvas._context.rendercanvas_context_hook
:no-index:


Context API
-----------

The class below describes the API and behavior that is expected of a context object.
Also see https://github.com/pygfx/rendercanvas/blob/main/rendercanvas/_context.py.

.. autoclass:: rendercanvas._context.ContextInterface
:members:
:no-index:


Adapter
-------

.. autoclass:: rendercanvas.utils.bitmappresentadapter.BitmapPresentAdapter
:members:
:no-index:
13 changes: 13 additions & 0 deletions docs/contexts.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Context API
===========

.. automodule:: rendercanvas.contexts

.. autoclass:: rendercanvas.contexts.BaseContext
:members:

.. autoclass:: rendercanvas.contexts.BitmapContext
:members:

.. autoclass:: rendercanvas.contexts.WgpuContext
:members:
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Welcome to the rendercanvas docs!

start
api
contexts
backends
utils
Gallery <gallery/index.rst>
Expand Down
4 changes: 2 additions & 2 deletions docs/start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Rendering using bitmaps:

.. code-block:: py

context = canvas.get_context("bitmap")
context = canvas.get_bitmap_context()

@canvas.request_draw
def animate():
Expand All @@ -61,7 +61,7 @@ Rendering with wgpu:

.. code-block:: py

context = canvas.get_context("wgpu")
context = canvas.get_wgpu_context()
context.configure(device)

@canvas.request_draw
Expand Down
2 changes: 0 additions & 2 deletions docs/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ Utils

utils_asyncs
utils_cube
utils_bitmappresentadapter.rst
utils_bitmaprenderingcontext.rst
5 changes: 0 additions & 5 deletions docs/utils_bitmappresentadapter.rst

This file was deleted.

5 changes: 0 additions & 5 deletions docs/utils_bitmaprenderingcontext.rst

This file was deleted.

2 changes: 1 addition & 1 deletion examples/drag.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

canvas = RenderCanvas(present_method=None, update_mode="continuous")

context = canvas.get_context("bitmap")
context = canvas.get_bitmap_context()


# The size of the blocks: hw is half the block width
Expand Down
2 changes: 1 addition & 1 deletion examples/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


canvas = RenderCanvas(update_mode="continuous")
context = canvas.get_context("bitmap")
context = canvas.get_bitmap_context()


@canvas.request_draw
Expand Down
2 changes: 1 addition & 1 deletion examples/snake.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

canvas = RenderCanvas(present_method=None, size=(640, 480), update_mode="continuous")

context = canvas.get_context("bitmap")
context = canvas.get_bitmap_context()

world = np.zeros((120, 160), np.uint8)
pos = [100, 100]
Expand Down
3 changes: 3 additions & 0 deletions rendercanvas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
from . import _coreutils
from ._enums import CursorShape, EventType, UpdateMode
from .base import BaseRenderCanvas, BaseLoop
from . import contexts
from . import utils


__all__ = ["BaseLoop", "BaseRenderCanvas", "CursorShape", "EventType", "UpdateMode"]
82 changes: 0 additions & 82 deletions rendercanvas/_context.py

This file was deleted.

46 changes: 23 additions & 23 deletions rendercanvas/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,34 @@ def get_extended_version() -> str:
# Sample first 3 parts of __version__
base_release = ".".join(__version__.split(".")[:3])

# Check release
if not release:
release = base_release
elif release != base_release:
warning(
f"{project_name} version from git ({release})"
f" and __version__ ({base_release}) don't match."
)

# Build the total version
version = release
# Start version string (__version__ string is leading)
version = base_release
tag_prefix = "#"

if release and release != base_release:
# Can happen between bumping and tagging. And also when merging a
# version bump into a working branch, because we use --first-parent.
release2, _post, _labels = get_version_info_from_git(first_parent=False)
if release2 != base_release:
warning(
f"{project_name} version from git ({release})"
f" and __version__ ({base_release}) don't match."
)
version += "+from_tag_" + release.replace(".", "_")
tag_prefix = "."

# Add git info
if post and post != "0":
version += f".post{post}"
if labels:
version += "+" + ".".join(labels)
version += tag_prefix + ".".join(labels)
elif labels and labels[-1] == "dirty":
version += "+" + ".".join(labels)
version += tag_prefix + ".".join(labels)

return version


def get_version_info_from_git() -> str:
def get_version_info_from_git(*, first_parent: bool = True) -> str:
"""
Get (release, post, labels) from Git.

Expand All @@ -80,15 +86,9 @@ def get_version_info_from_git() -> str:
git-hash and optionally a dirty flag.
"""
# Call out to Git
command = [
"git",
"describe",
"--long",
"--always",
"--tags",
"--dirty",
"--first-parent",
]
command = ["git", "describe", "--long", "--always", "--tags", "--dirty"]
if first_parent:
command.append("--first-parent")
try:
p = subprocess.run(command, check=False, cwd=repo_dir, capture_output=True)
except Exception as e:
Expand Down
Loading