Added SDK

This commit is contained in:
Andrew Zambazos
2026-06-11 14:01:22 +12:00
commit c0395a49bd
2155 changed files with 451005 additions and 0 deletions
+204
View File
@@ -0,0 +1,204 @@
/**************************************************************************************************
* This file is a part of Ultralight. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include <Ultralight/Defines.h>
#include <Ultralight/RefPtr.h>
#include <Ultralight/Bitmap.h>
#include <Ultralight/Geometry.h>
namespace ultralight {
///
/// User-defined pixel buffer surface.
///
/// The library uses this to store pixel data when rendering Views on the CPU (see
/// ViewConfig::is_accelerated).
///
/// You can provide the library with your own Surface implementation to reduce the latency of
/// displaying pixels in your application (Views will be drawn directly to a block of memory
/// controlled by you).
///
/// When a View is rendered on the CPU, you can retrieve the backing Surface via View::surface().
///
/// @pre This is automatically managed for you when using App::Create(), if you want to override
/// Surface or SurfaceFactory, you'll need to use Renderer::Create() instead.
///
/// ## Default Implementation
///
/// A default Surface implementation, BitmapSurface, is automatically provided by the library when
/// you call Renderer::Create() without defining a custom SurfaceFactory.
///
/// You should cast the Surface to a BitmapSurface to access the underlying Bitmap.
///
/// ## Setting the Surface Implementation
///
/// To define your own implementation, you should inherit from this class, handle the virtual
/// member functions, and then define a custom SurfaceFactory that creates/destroys an
/// instance of your class.
///
/// After that, you should pass an instance of your custom SurfaceFactory class to
/// Platform::set_surface_factory() before calling Renderer::Create().
///
class UExport Surface {
public:
virtual ~Surface();
///
/// Width (in pixels).
///
virtual uint32_t width() const = 0;
///
/// Height (in pixels).
///
virtual uint32_t height() const = 0;
///
/// Number of bytes between rows (usually width * 4)
///
virtual uint32_t row_bytes() const = 0;
///
/// Size in bytes.
///
virtual size_t size() const = 0;
///
/// Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.
///
/// @note Native pixel format is premultiplied BGRA 32-bit (8 bits per channel).
///
virtual void* LockPixels() = 0;
///
/// Unlock the pixel buffer.
///
virtual void UnlockPixels() = 0;
///
/// Resize the pixel buffer to a certain width and height (both in pixels).
///
/// This should never be called while pixels are locked.
///
virtual void Resize(uint32_t width, uint32_t height) = 0;
///
/// Set the dirty bounds to a certain value.
///
/// This is called after the Renderer paints to an area of the pixel buffer. (The new value will
/// be joined with the existing dirty_bounds())
///
virtual void set_dirty_bounds(const IntRect& bounds);
///
/// Get the dirty bounds.
///
/// This value can be used to determine which portion of the pixel buffer has been updated since
/// the last call to ClearDirtyBounds().
///
/// The general algorithm to determine if a Surface needs display is:
/// <pre>
/// if (!surface.dirty_bounds().IsEmpty()) {
/// // Surface pixels are dirty and needs display.
/// // Cast Surface to native Surface and use it here (pseudo code)
/// DisplaySurface(surface);
///
/// // Once you're done, clear the dirty bounds:
/// surface.ClearDirtyBounds();
/// }
/// </pre>
///
virtual IntRect dirty_bounds() const;
///
/// Clear the dirty bounds.
///
/// You should call this after you're done displaying the Surface.
///
virtual void ClearDirtyBounds();
protected:
Surface();
IntRect dirty_bounds_;
};
///
/// User-defined factory to provide your own surface implementation.
///
/// The library uses this to create/destroy Surface instances when rendering Views on the CPU.
///
/// @pre This is automatically managed for you when using App::Create(), if you want to override
/// Surface or SurfaceFactory, you'll need to use Renderer::Create() instead.
///
/// ## Setting the Surface Factory
///
/// The default factory creates/destroys a BitmapSurface but you can override this by providing your
/// own factory to Platform::set_surface_factory().
///
class UExport SurfaceFactory {
public:
virtual ~SurfaceFactory();
///
/// Create a native Surface with a certain width and height (in pixels).
///
virtual Surface* CreateSurface(uint32_t width, uint32_t height) = 0;
///
/// Destroy a native Surface previously created by CreateSurface().
///
virtual void DestroySurface(Surface* surface) = 0;
};
///
/// The default surface implementation, backed by a bitmap.
///
/// This is automatically provided by the library when you call Renderer::Create() without defining
/// a custom SurfaceFactory.
///
/// This implementation uses a Bitmap to store pixel data (retrieve it via BitmapSurface::bitmap()).
///
class UExport BitmapSurface : public Surface {
public:
virtual uint32_t width() const override;
virtual uint32_t height() const override;
virtual uint32_t row_bytes() const override;
virtual size_t size() const override;
virtual void* LockPixels() override;
virtual void UnlockPixels() override;
virtual void Resize(uint32_t width, uint32_t height) override;
///
/// Get the underlying Bitmap.
///
RefPtr<Bitmap> bitmap();
protected:
BitmapSurface(uint32_t width, uint32_t height);
virtual ~BitmapSurface();
BitmapSurface(const BitmapSurface&) = delete;
void operator=(const BitmapSurface&) = delete;
friend class BitmapSurfaceFactory;
void* impl_;
};
///
/// Get the default Bitmap Surface Factory singleton. (Do not destroy this, this singleton is owned
/// by the library).
///
UExport SurfaceFactory* GetBitmapSurfaceFactory();
} // namespace ultralight