From b932f0d91dad470baefafe291d4958de4ff01d47 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 10 Oct 2013 10:55:29 -0700 Subject: [PATCH] Stop using shared GL contexts and move to native OS surface sharing --- azure-c.cpp | 21 ++++++++------ azure-c.h | 11 ++++++-- azure.rc | 2 ++ azure.rs | 15 ++++++++-- azure_hl.rs | 80 +++++++++++++++++++++++++++++++++++------------------ 5 files changed, 89 insertions(+), 40 deletions(-) diff --git a/azure-c.cpp b/azure-c.cpp index 5a20e0e..a6edb15 100644 --- a/azure-c.cpp +++ b/azure-c.cpp @@ -152,8 +152,9 @@ AzReleaseColorPattern(AzColorPatternRef aColorPattern) { } extern "C" AzSkiaSharedGLContextRef -AzCreateSkiaSharedGLContext(AzGLContext aGLContext, void *extra, AzIntSize *aSize) { - SkNativeSharedGLContext *sharedGLContext = new SkNativeSharedGLContext(aGLContext, extra); +AzCreateSkiaSharedGLContext(AzGLNativeContextRef aNativeContext, AzIntSize *aSize) { + GrGLNativeContext* nativeContext = reinterpret_cast(aNativeContext); + SkNativeSharedGLContext *sharedGLContext = new SkNativeSharedGLContext(*nativeContext); if (sharedGLContext == NULL) { return NULL; } @@ -181,10 +182,10 @@ AzSkiaSharedGLContextGetFBOID(AzSkiaSharedGLContextRef aGLContext) { return sharedGLContext->getFBOID(); } -extern "C" unsigned int -AzSkiaSharedGLContextGetTextureID(AzSkiaSharedGLContextRef aGLContext) { - SkNativeSharedGLContext *sharedGLContext = static_cast(aGLContext); - return sharedGLContext->getTextureID(); +extern "C" AzSkiaGrGLSharedSurfaceRef +AzSkiaSharedGLContextStealSurface(AzSkiaSharedGLContextRef aGLContext) { + SkNativeSharedGLContext *sharedGLContext = static_cast(aGLContext); + return reinterpret_cast(sharedGLContext->stealSurface()); } extern "C" AzSkiaGrContextRef @@ -228,7 +229,9 @@ AzCreateDrawTargetForData(AzBackendType aBackend, unsigned char *aData, AzIntSiz *size, aStride, surfaceFormat); - target->AddRef(); + if (target != NULL) { + target->AddRef(); + } return target; } @@ -242,7 +245,9 @@ AzCreateSkiaDrawTargetForFBO(AzSkiaSharedGLContextRef aGLContext, AzIntSize *aSi grContext, *size, surfaceFormat); - target->AddRef(); + if (target != NULL) { + target->AddRef(); + } return target; } diff --git a/azure-c.h b/azure-c.h index d61bcb7..a134562 100644 --- a/azure-c.h +++ b/azure-c.h @@ -283,7 +283,10 @@ typedef struct _AzNativeFont { typedef void* AzGradientStopsRef; typedef void* AzSkiaSharedGLContextRef; +typedef void* AzSkiaSharedGrGLContextRef; typedef void* AzSkiaGrContextRef; +typedef void* AzSkiaGrGLSharedSurfaceRef; +typedef void* AzSkiaGrGLSharedContextRef; typedef void* AzDrawTargetRef; typedef void* AzPatternRef; typedef void* AzColorPatternRef; @@ -292,17 +295,19 @@ typedef void* AzGlyphRenderingOptionsRef; typedef void* AzSourceSurfaceRef; typedef void* AzDrawSurfaceOptionsRef; typedef void* AzDataSourceSurfaceRef; +typedef void* AzGLContextMetadataRef; typedef GrGLSharedContext AzGLContext; +typedef GrGLNativeContext* AzGLNativeContextRef; AzColorPatternRef AzCreateColorPattern(AzColor *aColor); void AzReleaseColorPattern(AzColorPatternRef aColorPattern); -AzSkiaSharedGLContextRef AzCreateSkiaSharedGLContext(GrGLSharedContext aSharedContext, void *extra, AzIntSize *aSize); +AzSkiaSharedGLContextRef AzCreateSkiaSharedGLContext(AzGLNativeContextRef aNativeContext, + AzIntSize *aSize); void AzRetainSkiaSharedGLContext(AzSkiaSharedGLContextRef aGLContext); -void AzReleaseSkiaShareGLContext(AzSkiaSharedGLContextRef aGLContext); +void AzReleaseSkiaSharedGLContext(AzSkiaSharedGLContextRef aGLContext); unsigned int AzSkiaSharedGLContextGetFBOID(AzSkiaSharedGLContextRef aGLContext); -unsigned int AzSkiaSharedGLContextGetTextureID(AzSkiaSharedGLContextRef aGLContext); AzSkiaGrContextRef AzSkiaSharedGLContextGetGrContext(AzSkiaSharedGLContextRef aGLContext); void AzSkiaSharedGLContextMakeCurrent(AzSkiaSharedGLContextRef aGLContext); void AzSkiaSharedGLContextFlush(AzSkiaSharedGLContextRef aGLContext); diff --git a/azure.rc b/azure.rc index fb2e196..c9448c2 100644 --- a/azure.rc +++ b/azure.rc @@ -13,6 +13,8 @@ extern mod extra; extern mod geom; extern mod layers; extern mod opengles; +#[cfg(target_os = "linux")] +extern mod xlib; #[cfg(not(target_os = "android"))] extern mod glfw; diff --git a/azure.rs b/azure.rs index c842872..c59f389 100644 --- a/azure.rs +++ b/azure.rs @@ -254,8 +254,12 @@ pub type AzGradientStopsRef = *c_void; pub type AzSkiaSharedGLContextRef = *c_void; +pub type AzSkiaSharedGrGLContextRef = *c_void; + pub type AzSkiaGrContextRef = *c_void; +pub type AzSkiaGrGLSharedSurfaceRef = *c_void; + pub type AzDrawTargetRef = *c_void; pub type AzPatternRef = *c_void; @@ -274,6 +278,12 @@ pub type AzDrawSurfaceOptionsRef = *AzDrawSurfaceOptions; pub type AzGLContext = *c_void; +pub type AzSkiaGrGLSharedContextRef = *c_void; + +pub type AzGLContextMetadataRef = *c_void; + +pub type AzGLNativeContextRef = *c_void; + #[link_args="-lazure"] extern { @@ -283,7 +293,8 @@ pub fn AzCreateColorPattern(aColor: *AzColor) -> AzColorPatternRef; pub fn AzReleaseColorPattern(aColorPattern: AzColorPatternRef); -pub fn AzCreateSkiaSharedGLContext(aGLContext: AzGLContext, extra: *c_void, aSize: *AzIntSize) -> AzSkiaSharedGLContextRef; +pub fn AzCreateSkiaSharedGLContext(aNativeContext: AzGLNativeContextRef, aSize: *AzIntSize) + -> AzSkiaSharedGLContextRef; pub fn AzRetainSkiaSharedGLContext(aGLContext: AzSkiaSharedGLContextRef); @@ -291,7 +302,7 @@ pub fn AzReleaseSkiaSharedGLContext(aGLContext: AzSkiaSharedGLContextRef); pub fn AzSkiaSharedGLContextGetFBOID(aGLContext: AzSkiaSharedGLContextRef) -> c_uint; -pub fn AzSkiaSharedGLContextGetTextureID(aGLContext: AzSkiaSharedGLContextRef) -> c_uint; +pub fn AzSkiaSharedGLContextStealSurface(aGLContext: AzSkiaSharedGLContextRef) -> AzSkiaGrGLSharedSurfaceRef; pub fn AzSkiaSharedGLContextGetGrContext(aGLContext: AzSkiaSharedGLContextRef) -> AzSkiaGrContextRef; diff --git a/azure_hl.rs b/azure_hl.rs index 156e67d..5dde74c 100644 --- a/azure_hl.rs +++ b/azure_hl.rs @@ -25,21 +25,25 @@ use azure::{AzReleaseColorPattern, AzReleaseDrawTarget}; use azure::{AzReleaseSourceSurface, AzRetainDrawTarget}; use azure::{AzSourceSurfaceGetDataSurface, AzSourceSurfaceGetFormat}; use azure::{AzSourceSurfaceGetSize, AzCreateSkiaDrawTargetForFBO, AzSkiaGetCurrentGLContext}; -use azure::{AzSkiaSharedGLContextMakeCurrent, AzSkiaSharedGLContextGetTextureID, AzSkiaSharedGLContextFlush}; +use azure::{AzSkiaSharedGLContextMakeCurrent, AzSkiaSharedGLContextStealSurface}; +use azure::{AzSkiaSharedGLContextFlush, AzSkiaGrGLSharedSurfaceRef}; -use std::libc::types::common::c99::{uint8_t, uint16_t}; -use std::libc::{c_void, size_t}; -use std::cast::transmute; -use std::ptr; -use std::ptr::{null, to_unsafe_ptr}; -use std::vec; +use extra::arc::Arc; use geom::matrix2d::Matrix2D; use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; -use layers::layers::TextureManager; use gl = opengles::gl2; -use extra::arc::Arc; +use layers::platform::surface::{NativeGraphicsMetadata, NativePaintingGraphicsContext}; +use std::libc::types::common::c99::{uint8_t, uint16_t}; +use std::libc::size_t; +use std::cast; +use std::ptr; +use std::ptr::{null, to_unsafe_ptr}; +use std::vec; + +#[cfg(target_os="linux")] +use std::libc::c_void; pub trait AsAzureRect { fn as_azure_rect(&self) -> AzRect; @@ -288,6 +292,12 @@ impl Drop for DrawTarget { } } +/// Contains the GL resources that Skia was holding onto that may be safely extracted. At the +/// moment this consists simply of the native surface. +pub struct StolenGLResources { + surface: AzSkiaGrGLSharedSurfaceRef, +} + impl DrawTarget { #[fixed_stack_segment] pub fn new(backend: BackendType, size: Size2D, format: SurfaceFormat) @@ -331,18 +341,20 @@ impl DrawTarget { #[fixed_stack_segment] pub fn new_with_fbo(backend: BackendType, - share_context: AzGLContext, + native_graphics_context: &NativePaintingGraphicsContext, size: Size2D, format: SurfaceFormat) -> DrawTarget { assert!(backend == SkiaBackend); unsafe { - let skia_context = AzCreateSkiaSharedGLContext(share_context, - current_display(), + let native_graphics_context = cast::transmute(native_graphics_context); + let skia_context = AzCreateSkiaSharedGLContext(native_graphics_context, &size.as_azure_int_size()); let azure_draw_target = AzCreateSkiaDrawTargetForFBO(skia_context, &size.as_azure_int_size(), format.as_azure_surface_format()); - if azure_draw_target == ptr::null() { fail!(~"null azure draw target"); } + if azure_draw_target == ptr::null() { + fail!(~"null azure draw target"); + } DrawTarget { azure_draw_target: azure_draw_target, data: None, @@ -382,13 +394,16 @@ impl DrawTarget { } } + /// Consumes this draw target and returns the underlying native surface and GL context, if they exist. #[fixed_stack_segment] - pub fn get_texture_id(&self) -> Option { + pub fn steal_gl_resources(self) -> Option { match self.skia_context { None => None, Some(ctx) => { unsafe { - Some(AzSkiaSharedGLContextGetTextureID(ctx)) + Some(StolenGLResources { + surface: AzSkiaSharedGLContextStealSurface(ctx), + }) } } } @@ -507,7 +522,7 @@ impl DrawTarget { #[fixed_stack_segment] pub fn set_transform(&self, matrix: &Matrix2D) { unsafe { - AzDrawTargetSetTransform(self.azure_draw_target, transmute(matrix)); + AzDrawTargetSetTransform(self.azure_draw_target, cast::transmute(matrix)); } } @@ -527,13 +542,6 @@ impl DrawTarget { } } -impl TextureManager for DrawTarget { - fn get_texture(&self) -> gl::GLuint { - self.get_texture_id().unwrap() - } -} - - // Ugly workaround for the lack of explicit self. pub fn clone_mutable_draw_target(draw_target: &mut DrawTarget) -> DrawTarget { return draw_target.clone(); @@ -657,13 +665,31 @@ pub fn current_gl_context() -> AzGLContext { #[cfg(target_os="linux")] #[fixed_stack_segment] -fn current_display() -> *c_void { +pub fn current_display() -> *c_void { use glfw; - unsafe { glfw::ffi::glfwGetX11Display() } + unsafe { + glfw::ffi::glfwGetX11Display() + } +} + +#[cfg(target_os="linux")] +#[fixed_stack_segment] +pub fn current_graphics_metadata() -> NativeGraphicsMetadata { + use xlib::xlib::XDisplayString; + unsafe { + XDisplayString(current_display()) + } } #[cfg(target_os="macos")] #[cfg(target_os="android")] -fn current_display() -> *c_void { - null() +#[fixed_stack_segment] +pub fn current_graphics_metadata() -> NativeGraphicsMetadata { + use opengles::cgl::{CGLGetCurrentContext, CGLGetPixelFormat}; + unsafe { + NativeGraphicsMetadata { + pixel_format: CGLGetPixelFormat(CGLGetCurrentContext()), + } + } } +