mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 03:47:31 +09:00
Compare commits
No commits in common. "1190eb1c6a485c5ab20817b28849a0aef2d3980c" and "78c309f1b38ff70b75ff7087b1e2ee3392ee0b1e" have entirely different histories.
1190eb1c6a
...
78c309f1b3
9 changed files with 0 additions and 743 deletions
|
|
@ -10,11 +10,9 @@
|
||||||
#include "mozilla/gfx/Rect.h" // for Rect
|
#include "mozilla/gfx/Rect.h" // for Rect
|
||||||
#include "mozilla/gfx/Types.h" // for Color
|
#include "mozilla/gfx/Types.h" // for Color
|
||||||
#include "mozilla/layers/Compositor.h" // for Compositor
|
#include "mozilla/layers/Compositor.h" // for Compositor
|
||||||
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
|
|
||||||
#include "mozilla/layers/CompositorTypes.h" // for DiagnosticFlags::COLOR
|
#include "mozilla/layers/CompositorTypes.h" // for DiagnosticFlags::COLOR
|
||||||
#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc
|
#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc
|
||||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||||
#include "gfxPrefs.h" // for gfxPrefs::WebRenderEnabled
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
@ -30,22 +28,6 @@ ColorLayerComposite::RenderLayer(const IntRect& aClipRect)
|
||||||
RenderWithAllMasks(this, mCompositor, aClipRect,
|
RenderWithAllMasks(this, mCompositor, aClipRect,
|
||||||
[&](EffectChain& effectChain, const IntRect& clipRect) {
|
[&](EffectChain& effectChain, const IntRect& clipRect) {
|
||||||
GenEffectChain(effectChain);
|
GenEffectChain(effectChain);
|
||||||
|
|
||||||
// Route simple 2D color primitives through the retained C display list.
|
|
||||||
// Masked or 3D layers continue through the established effect path until
|
|
||||||
// equivalent WebRender primitives are available for those cases.
|
|
||||||
CompositorOGL* compositorOGL = mCompositor->AsCompositorOGL();
|
|
||||||
if (gfxPrefs::WebRenderEnabled() && compositorOGL &&
|
|
||||||
!effectChain.mSecondaryEffects[EffectTypes::MASK] &&
|
|
||||||
GetEffectiveMixBlendMode() == CompositionOp::OP_OVER &&
|
|
||||||
transform.Is2D() && !clipRect.IsEmpty()) {
|
|
||||||
if (compositorOGL->DrawWebRenderRect(rect, GetColor(),
|
|
||||||
GetEffectiveOpacity(), transform,
|
|
||||||
clipRect)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mCompositor->DrawQuad(rect, clipRect, effectChain, GetEffectiveOpacity(),
|
mCompositor->DrawQuad(rect, clipRect, effectChain, GetEffectiveOpacity(),
|
||||||
transform);
|
transform);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,6 @@ CompositorOGL::CompositorOGL(CompositorBridgeParent* aParent,
|
||||||
: Compositor(aWidget, aParent)
|
: Compositor(aWidget, aParent)
|
||||||
, mWidgetSize(-1, -1)
|
, mWidgetSize(-1, -1)
|
||||||
, mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
|
, mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
|
||||||
, mWebRenderContext(nullptr)
|
|
||||||
, mHasBGRA(0)
|
, mHasBGRA(0)
|
||||||
, mUseExternalSurfaceSize(aUseExternalSurfaceSize)
|
, mUseExternalSurfaceSize(aUseExternalSurfaceSize)
|
||||||
, mFrameInProgress(false)
|
, mFrameInProgress(false)
|
||||||
|
|
@ -166,11 +165,6 @@ CompositorOGL::Destroy()
|
||||||
void
|
void
|
||||||
CompositorOGL::CleanupResources()
|
CompositorOGL::CleanupResources()
|
||||||
{
|
{
|
||||||
if (mWebRenderContext) {
|
|
||||||
wr_context_destroy(mWebRenderContext);
|
|
||||||
mWebRenderContext = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mGLContext)
|
if (!mGLContext)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1000,146 +994,6 @@ CompositorOGL::DrawTriangle(const gfx::TexturedTriangle& aTriangle,
|
||||||
aOpacity, aTransform, aVisibleRect);
|
aOpacity, aTransform, aVisibleRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
CompositorOGL::DrawWebRenderContext(wr_context* aContext,
|
|
||||||
const IntRect& aClipRect)
|
|
||||||
{
|
|
||||||
if (!aContext) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wr_frame* frame = wr_context_build_frame(aContext);
|
|
||||||
if (frame) {
|
|
||||||
DrawWebRenderFrame(*frame, aClipRect);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
CompositorOGL::DrawWebRenderRect(const Rect& aRect,
|
|
||||||
const Color& aColor,
|
|
||||||
Float aOpacity,
|
|
||||||
const Matrix4x4& aTransform,
|
|
||||||
const IntRect& aClipRect)
|
|
||||||
{
|
|
||||||
if (!mFrameInProgress || aClipRect.IsEmpty() || !aTransform.Is2D()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!mWebRenderContext) {
|
|
||||||
mWebRenderContext = wr_context_create(8);
|
|
||||||
}
|
|
||||||
if (!mWebRenderContext) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wr_context_clear(mWebRenderContext);
|
|
||||||
wr_context_set_viewport(mWebRenderContext,
|
|
||||||
wr_rect{ Float(aClipRect.x), Float(aClipRect.y),
|
|
||||||
Float(aClipRect.width), Float(aClipRect.height) });
|
|
||||||
Matrix transform = aTransform.As2D();
|
|
||||||
wr_context_set_transform(mWebRenderContext,
|
|
||||||
wr_transform{ transform._11, transform._12,
|
|
||||||
transform._21, transform._22,
|
|
||||||
transform._31, transform._32 });
|
|
||||||
wr_context_set_opacity(mWebRenderContext, aOpacity);
|
|
||||||
if (!wr_display_list_push_rect(mWebRenderContext,
|
|
||||||
wr_rect{ aRect.x, aRect.y,
|
|
||||||
aRect.width, aRect.height },
|
|
||||||
wr_color{ aColor.r, aColor.g,
|
|
||||||
aColor.b, aColor.a })) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool drawn = DrawWebRenderContext(mWebRenderContext, aClipRect);
|
|
||||||
wr_context_clear(mWebRenderContext);
|
|
||||||
return drawn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CompositorOGL::DrawWebRenderFrame(const wr_frame& aFrame,
|
|
||||||
const IntRect& aClipRect)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mFrameInProgress, "frame not started");
|
|
||||||
MOZ_ASSERT(mCurrentRenderTarget, "No destination");
|
|
||||||
|
|
||||||
if (!aFrame.quads || !aFrame.batches ||
|
|
||||||
aFrame.quad_count == 0 || aFrame.batch_count == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeCurrent();
|
|
||||||
|
|
||||||
// This first adapter handles solid rectangles. It deliberately reuses the
|
|
||||||
// compositor's existing four-rect uniform and triangle VBO path, so the
|
|
||||||
// retained C display list is submitted to the GPU without a CPU raster pass.
|
|
||||||
EffectSolidColor effect(Color(0, 0, 0, 0));
|
|
||||||
ShaderConfigOGL config = GetShaderConfigFor(&effect);
|
|
||||||
ShaderProgramOGL* program = GetShaderProgramFor(config);
|
|
||||||
if (!program) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IntPoint offset = mCurrentRenderTarget->GetOrigin();
|
|
||||||
ActivateProgram(program);
|
|
||||||
program->SetProjectionMatrix(mProjMatrix);
|
|
||||||
program->SetLayerTransform(Matrix4x4());
|
|
||||||
program->SetRenderOffset(offset.x, offset.y);
|
|
||||||
|
|
||||||
ScopedGLState scopedScissorTestState(mGLContext, LOCAL_GL_SCISSOR_TEST, true);
|
|
||||||
ScopedScissorRect autoScissorRect(mGLContext,
|
|
||||||
aClipRect.x,
|
|
||||||
FlipY(aClipRect.y + aClipRect.height),
|
|
||||||
aClipRect.width,
|
|
||||||
aClipRect.height);
|
|
||||||
|
|
||||||
for (size_t batchIndex = 0; batchIndex < aFrame.batch_count; ++batchIndex) {
|
|
||||||
const wr_gpu_batch& batch = aFrame.batches[batchIndex];
|
|
||||||
if (batch.first_quad > aFrame.quad_count ||
|
|
||||||
batch.quad_count > aFrame.quad_count - batch.first_quad) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
IntRect batchClip = aClipRect;
|
|
||||||
if (batch.has_clip) {
|
|
||||||
IntRect primitiveClip(int32_t(batch.clip_rect.x),
|
|
||||||
int32_t(batch.clip_rect.y),
|
|
||||||
int32_t(batch.clip_rect.width),
|
|
||||||
int32_t(batch.clip_rect.height));
|
|
||||||
batchClip.IntersectRect(batchClip, primitiveClip);
|
|
||||||
if (batchClip.IsEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ScopedScissorRect batchScissor(
|
|
||||||
mGLContext, batchClip.x, FlipY(batchClip.y + batchClip.height),
|
|
||||||
batchClip.width, batchClip.height);
|
|
||||||
|
|
||||||
program->SetLayerTransform(Matrix4x4::From2D(
|
|
||||||
Matrix(batch.transform.m11, batch.transform.m12,
|
|
||||||
batch.transform.m21, batch.transform.m22,
|
|
||||||
batch.transform.m31, batch.transform.m32)));
|
|
||||||
|
|
||||||
uint32_t remaining = batch.quad_count;
|
|
||||||
uint32_t quadIndex = batch.first_quad;
|
|
||||||
program->SetRenderColor(Color(batch.color.r, batch.color.g,
|
|
||||||
batch.color.b, batch.color.a));
|
|
||||||
|
|
||||||
while (remaining) {
|
|
||||||
Rect rects[4] = {};
|
|
||||||
int count = remaining > 4 ? 4 : int(remaining);
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
const wr_gpu_quad& quad = aFrame.quads[quadIndex + i];
|
|
||||||
rects[i] = Rect(quad.rect.x, quad.rect.y,
|
|
||||||
quad.rect.width, quad.rect.height);
|
|
||||||
}
|
|
||||||
BindAndDrawQuads(program, count, rects, nullptr);
|
|
||||||
quadIndex += count;
|
|
||||||
remaining -= count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Geometry>
|
template<typename Geometry>
|
||||||
void
|
void
|
||||||
CompositorOGL::DrawGeometry(const Geometry& aGeometry,
|
CompositorOGL::DrawGeometry(const Geometry& aGeometry,
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
#include "mozilla/gfx/Rect.h" // for Rect, IntRect
|
#include "mozilla/gfx/Rect.h" // for Rect, IntRect
|
||||||
#include "mozilla/gfx/Triangle.h" // for Triangle
|
#include "mozilla/gfx/Triangle.h" // for Triangle
|
||||||
#include "mozilla/gfx/Types.h" // for Float, SurfaceFormat, etc
|
#include "mozilla/gfx/Types.h" // for Float, SurfaceFormat, etc
|
||||||
#include "mozilla/gfx/webrender.h" // for wr_frame
|
|
||||||
#include "mozilla/layers/Compositor.h" // for SurfaceInitMode, Compositor, etc
|
#include "mozilla/layers/Compositor.h" // for SurfaceInitMode, Compositor, etc
|
||||||
#include "mozilla/layers/CompositorTypes.h" // for MaskType::MaskType::NumMaskTypes, etc
|
#include "mozilla/layers/CompositorTypes.h" // for MaskType::MaskType::NumMaskTypes, etc
|
||||||
#include "mozilla/layers/LayersTypes.h"
|
#include "mozilla/layers/LayersTypes.h"
|
||||||
|
|
@ -212,17 +211,6 @@ public:
|
||||||
const gfx::Matrix4x4& aTransform,
|
const gfx::Matrix4x4& aTransform,
|
||||||
const gfx::Rect& aVisibleRect) override;
|
const gfx::Rect& aVisibleRect) override;
|
||||||
|
|
||||||
// Consume solid retained-display-list quads through the existing GPU path.
|
|
||||||
bool DrawWebRenderContext(wr_context* aContext,
|
|
||||||
const gfx::IntRect& aClipRect);
|
|
||||||
bool DrawWebRenderRect(const gfx::Rect& aRect,
|
|
||||||
const gfx::Color& aColor,
|
|
||||||
gfx::Float aOpacity,
|
|
||||||
const gfx::Matrix4x4& aTransform,
|
|
||||||
const gfx::IntRect& aClipRect);
|
|
||||||
void DrawWebRenderFrame(const wr_frame& aFrame,
|
|
||||||
const gfx::IntRect& aClipRect);
|
|
||||||
|
|
||||||
virtual void EndFrame() override;
|
virtual void EndFrame() override;
|
||||||
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) override;
|
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) override;
|
||||||
|
|
||||||
|
|
@ -339,7 +327,6 @@ private:
|
||||||
|
|
||||||
/** Currently bound render target */
|
/** Currently bound render target */
|
||||||
RefPtr<CompositingRenderTargetOGL> mCurrentRenderTarget;
|
RefPtr<CompositingRenderTargetOGL> mCurrentRenderTarget;
|
||||||
wr_context* mWebRenderContext;
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
CompositingRenderTargetOGL* mWindowRenderTarget;
|
CompositingRenderTargetOGL* mWindowRenderTarget;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ if CONFIG['MOZ_TREE_CAIRO']:
|
||||||
|
|
||||||
DIRS += [
|
DIRS += [
|
||||||
'2d',
|
'2d',
|
||||||
'wr',
|
|
||||||
'ycbcr',
|
'ycbcr',
|
||||||
'angle',
|
'angle',
|
||||||
'src',
|
'src',
|
||||||
|
|
|
||||||
|
|
@ -409,8 +409,6 @@ private:
|
||||||
|
|
||||||
DECL_GFX_PREF(Once, "gfx.use-iosurface-textures", UseIOSurfaceTextures, bool, false);
|
DECL_GFX_PREF(Once, "gfx.use-iosurface-textures", UseIOSurfaceTextures, bool, false);
|
||||||
|
|
||||||
DECL_GFX_PREF(Live, "gfx.webrender.enabled", WebRenderEnabled, bool, false);
|
|
||||||
|
|
||||||
// These times should be in milliseconds
|
// These times should be in milliseconds
|
||||||
DECL_GFX_PREF(Once, "gfx.touch.resample.delay-threshold", TouchResampleVsyncDelayThreshold, int32_t, 20);
|
DECL_GFX_PREF(Once, "gfx.touch.resample.delay-threshold", TouchResampleVsyncDelayThreshold, int32_t, 20);
|
||||||
DECL_GFX_PREF(Once, "gfx.touch.resample.max-predict", TouchResampleMaxPredict, int32_t, 8);
|
DECL_GFX_PREF(Once, "gfx.touch.resample.max-predict", TouchResampleMaxPredict, int32_t, 8);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
|
|
||||||
# The retained display-list core is deliberately C-only. GPU backends can
|
|
||||||
# consume the emitted instanced-quad stream through a stable C ABI.
|
|
||||||
EXPORTS.mozilla.gfx += [
|
|
||||||
'webrender.h',
|
|
||||||
]
|
|
||||||
|
|
||||||
SOURCES += [
|
|
||||||
'webrender.c',
|
|
||||||
]
|
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
|
||||||
|
|
@ -1,447 +0,0 @@
|
||||||
#include "webrender.h"
|
|
||||||
|
|
||||||
#include <float.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
wr_rect rect;
|
|
||||||
wr_color color;
|
|
||||||
wr_transform transform;
|
|
||||||
wr_rect clip_rect;
|
|
||||||
uint8_t has_clip;
|
|
||||||
} wr_rect_command;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
wr_transform transform;
|
|
||||||
float opacity;
|
|
||||||
size_t clip_depth;
|
|
||||||
} wr_display_state;
|
|
||||||
|
|
||||||
struct wr_context {
|
|
||||||
wr_rect_command* commands;
|
|
||||||
size_t command_count;
|
|
||||||
size_t command_capacity;
|
|
||||||
|
|
||||||
wr_gpu_quad* quads;
|
|
||||||
size_t quad_count;
|
|
||||||
size_t quad_capacity;
|
|
||||||
|
|
||||||
wr_gpu_batch* batches;
|
|
||||||
size_t batch_count;
|
|
||||||
size_t batch_capacity;
|
|
||||||
|
|
||||||
wr_rect viewport;
|
|
||||||
wr_transform transform;
|
|
||||||
float opacity;
|
|
||||||
wr_rect* clip_stack;
|
|
||||||
size_t clip_depth;
|
|
||||||
size_t clip_capacity;
|
|
||||||
wr_display_state* state_stack;
|
|
||||||
size_t state_depth;
|
|
||||||
size_t state_capacity;
|
|
||||||
wr_frame frame;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
wr_size_mul_overflow(size_t a, size_t b)
|
|
||||||
{
|
|
||||||
return b != 0 && a > SIZE_MAX / b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wr_reserve(void** data, size_t* capacity, size_t count, size_t element_size)
|
|
||||||
{
|
|
||||||
size_t new_capacity;
|
|
||||||
void* new_data;
|
|
||||||
|
|
||||||
if (count <= *capacity)
|
|
||||||
return 1;
|
|
||||||
if (element_size == 0 || wr_size_mul_overflow(count, element_size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
new_capacity = *capacity ? *capacity : 8;
|
|
||||||
while (new_capacity < count) {
|
|
||||||
if (new_capacity > SIZE_MAX / 2) {
|
|
||||||
new_capacity = count;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
new_capacity *= 2;
|
|
||||||
}
|
|
||||||
if (wr_size_mul_overflow(new_capacity, element_size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
new_data = realloc(*data, new_capacity * element_size);
|
|
||||||
if (!new_data)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*data = new_data;
|
|
||||||
*capacity = new_capacity;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wr_valid_rect(wr_rect rect)
|
|
||||||
{
|
|
||||||
return isfinite(rect.x) && isfinite(rect.y) &&
|
|
||||||
isfinite(rect.width) && isfinite(rect.height) &&
|
|
||||||
rect.width > 0.0f && rect.height > 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wr_valid_transform(wr_transform transform)
|
|
||||||
{
|
|
||||||
return isfinite(transform.m11) && isfinite(transform.m12) &&
|
|
||||||
isfinite(transform.m21) && isfinite(transform.m22) &&
|
|
||||||
isfinite(transform.m31) && isfinite(transform.m32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static wr_transform
|
|
||||||
wr_identity_transform(void)
|
|
||||||
{
|
|
||||||
wr_transform transform = { 1, 0, 0, 1, 0, 0 };
|
|
||||||
return transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wr_transform
|
|
||||||
wr_multiply_transform(wr_transform a, wr_transform b)
|
|
||||||
{
|
|
||||||
wr_transform result;
|
|
||||||
result.m11 = a.m11 * b.m11 + a.m21 * b.m12;
|
|
||||||
result.m12 = a.m12 * b.m11 + a.m22 * b.m12;
|
|
||||||
result.m21 = a.m11 * b.m21 + a.m21 * b.m22;
|
|
||||||
result.m22 = a.m12 * b.m21 + a.m22 * b.m22;
|
|
||||||
result.m31 = a.m11 * b.m31 + a.m21 * b.m32 + a.m31;
|
|
||||||
result.m32 = a.m12 * b.m31 + a.m22 * b.m32 + a.m32;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wr_rect
|
|
||||||
wr_empty_rect(void)
|
|
||||||
{
|
|
||||||
wr_rect rect = { 0, 0, 0, 0 };
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float
|
|
||||||
wr_clamp01(float value)
|
|
||||||
{
|
|
||||||
if (value < 0.0f)
|
|
||||||
return 0.0f;
|
|
||||||
if (value > 1.0f)
|
|
||||||
return 1.0f;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wr_color
|
|
||||||
wr_normalize_color(wr_color color)
|
|
||||||
{
|
|
||||||
color.r = wr_clamp01(color.r);
|
|
||||||
color.g = wr_clamp01(color.g);
|
|
||||||
color.b = wr_clamp01(color.b);
|
|
||||||
color.a = wr_clamp01(color.a);
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wr_colors_equal(wr_color a, wr_color b)
|
|
||||||
{
|
|
||||||
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wr_rects_equal(wr_rect a, wr_rect b)
|
|
||||||
{
|
|
||||||
return a.x == b.x && a.y == b.y &&
|
|
||||||
a.width == b.width && a.height == b.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wr_intersects(wr_rect a, wr_rect b)
|
|
||||||
{
|
|
||||||
return a.x < b.x + b.width && a.x + a.width > b.x &&
|
|
||||||
a.y < b.y + b.height && a.y + a.height > b.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wr_rect
|
|
||||||
wr_intersect_rect(wr_rect a, wr_rect b)
|
|
||||||
{
|
|
||||||
float left = a.x > b.x ? a.x : b.x;
|
|
||||||
float top = a.y > b.y ? a.y : b.y;
|
|
||||||
float right = a.x + a.width < b.x + b.width ?
|
|
||||||
a.x + a.width : b.x + b.width;
|
|
||||||
float bottom = a.y + a.height < b.y + b.height ?
|
|
||||||
a.y + a.height : b.y + b.height;
|
|
||||||
wr_rect result = { left, top, right - left, bottom - top };
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wr_rect
|
|
||||||
wr_transform_bounds(wr_rect rect, wr_transform transform)
|
|
||||||
{
|
|
||||||
float x1 = rect.x * transform.m11 + rect.y * transform.m21 + transform.m31;
|
|
||||||
float y1 = rect.x * transform.m12 + rect.y * transform.m22 + transform.m32;
|
|
||||||
float x2 = (rect.x + rect.width) * transform.m11 +
|
|
||||||
rect.y * transform.m21 + transform.m31;
|
|
||||||
float y2 = (rect.x + rect.width) * transform.m12 +
|
|
||||||
rect.y * transform.m22 + transform.m32;
|
|
||||||
float x3 = rect.x * transform.m11 +
|
|
||||||
(rect.y + rect.height) * transform.m21 + transform.m31;
|
|
||||||
float y3 = rect.x * transform.m12 +
|
|
||||||
(rect.y + rect.height) * transform.m22 + transform.m32;
|
|
||||||
float x4 = (rect.x + rect.width) * transform.m11 +
|
|
||||||
(rect.y + rect.height) * transform.m21 + transform.m31;
|
|
||||||
float y4 = (rect.x + rect.width) * transform.m12 +
|
|
||||||
(rect.y + rect.height) * transform.m22 + transform.m32;
|
|
||||||
float left = fminf(fminf(x1, x2), fminf(x3, x4));
|
|
||||||
float right = fmaxf(fmaxf(x1, x2), fmaxf(x3, x4));
|
|
||||||
float top = fminf(fminf(y1, y2), fminf(y3, y4));
|
|
||||||
float bottom = fmaxf(fmaxf(y1, y2), fmaxf(y3, y4));
|
|
||||||
wr_rect result = { left, top, right - left, bottom - top };
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
wr_context*
|
|
||||||
wr_context_create(size_t initial_capacity)
|
|
||||||
{
|
|
||||||
wr_context* context = (wr_context*)calloc(1, sizeof(*context));
|
|
||||||
if (!context)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
context->viewport.x = -FLT_MAX;
|
|
||||||
context->viewport.y = -FLT_MAX;
|
|
||||||
context->viewport.width = FLT_MAX;
|
|
||||||
context->viewport.height = FLT_MAX;
|
|
||||||
context->transform = wr_identity_transform();
|
|
||||||
context->opacity = 1.0f;
|
|
||||||
|
|
||||||
if (initial_capacity &&
|
|
||||||
!wr_reserve((void**)&context->commands, &context->command_capacity,
|
|
||||||
initial_capacity, sizeof(*context->commands))) {
|
|
||||||
wr_context_destroy(context);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wr_context_destroy(wr_context* context)
|
|
||||||
{
|
|
||||||
if (!context)
|
|
||||||
return;
|
|
||||||
free(context->commands);
|
|
||||||
free(context->quads);
|
|
||||||
free(context->batches);
|
|
||||||
free(context->clip_stack);
|
|
||||||
free(context->state_stack);
|
|
||||||
free(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wr_context_clear(wr_context* context)
|
|
||||||
{
|
|
||||||
if (!context)
|
|
||||||
return;
|
|
||||||
context->command_count = 0;
|
|
||||||
context->quad_count = 0;
|
|
||||||
context->batch_count = 0;
|
|
||||||
context->clip_depth = 0;
|
|
||||||
context->state_depth = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wr_context_set_viewport(wr_context* context, wr_rect viewport)
|
|
||||||
{
|
|
||||||
if (context && wr_valid_rect(viewport))
|
|
||||||
context->viewport = viewport;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wr_context_set_transform(wr_context* context, wr_transform transform)
|
|
||||||
{
|
|
||||||
if (context && wr_valid_transform(transform))
|
|
||||||
context->transform = transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wr_context_set_opacity(wr_context* context, float opacity)
|
|
||||||
{
|
|
||||||
if (context && isfinite(opacity)) {
|
|
||||||
context->opacity = wr_clamp01(opacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
wr_display_list_push_stacking_context(wr_context* context,
|
|
||||||
wr_transform transform,
|
|
||||||
float opacity)
|
|
||||||
{
|
|
||||||
wr_display_state state;
|
|
||||||
|
|
||||||
if (!context || !wr_valid_transform(transform) || !isfinite(opacity) ||
|
|
||||||
context->state_depth == SIZE_MAX)
|
|
||||||
return 0;
|
|
||||||
if (!wr_reserve((void**)&context->state_stack, &context->state_capacity,
|
|
||||||
context->state_depth + 1, sizeof(*context->state_stack)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
state.transform = context->transform;
|
|
||||||
state.opacity = context->opacity;
|
|
||||||
state.clip_depth = context->clip_depth;
|
|
||||||
context->state_stack[context->state_depth++] = state;
|
|
||||||
context->transform = wr_multiply_transform(context->transform, transform);
|
|
||||||
context->opacity = wr_clamp01(context->opacity * wr_clamp01(opacity));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wr_display_list_pop_stacking_context(wr_context* context)
|
|
||||||
{
|
|
||||||
wr_display_state state;
|
|
||||||
|
|
||||||
if (!context || !context->state_depth)
|
|
||||||
return;
|
|
||||||
state = context->state_stack[--context->state_depth];
|
|
||||||
context->transform = state.transform;
|
|
||||||
context->opacity = state.opacity;
|
|
||||||
context->clip_depth = state.clip_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
wr_display_list_push_clip(wr_context* context, wr_rect clip)
|
|
||||||
{
|
|
||||||
wr_rect effective_clip;
|
|
||||||
|
|
||||||
if (!context || !wr_valid_rect(clip) ||
|
|
||||||
context->clip_depth == SIZE_MAX)
|
|
||||||
return 0;
|
|
||||||
if (!wr_reserve((void**)&context->clip_stack, &context->clip_capacity,
|
|
||||||
context->clip_depth + 1, sizeof(*context->clip_stack)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
effective_clip = clip;
|
|
||||||
if (context->clip_depth)
|
|
||||||
effective_clip = wr_intersect_rect(
|
|
||||||
context->clip_stack[context->clip_depth - 1], clip);
|
|
||||||
context->clip_stack[context->clip_depth++] = effective_clip;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wr_display_list_pop_clip(wr_context* context)
|
|
||||||
{
|
|
||||||
if (context && context->clip_depth)
|
|
||||||
--context->clip_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
wr_display_list_push_rect(wr_context* context, wr_rect rect, wr_color color)
|
|
||||||
{
|
|
||||||
return context ? wr_display_list_push_transformed_rect(
|
|
||||||
context, rect, color, context->transform) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
wr_display_list_push_transformed_rect(wr_context* context, wr_rect rect,
|
|
||||||
wr_color color, wr_transform transform)
|
|
||||||
{
|
|
||||||
wr_rect clip_rect = context && context->clip_depth ?
|
|
||||||
context->clip_stack[context->clip_depth - 1] :
|
|
||||||
context ? context->viewport : wr_empty_rect();
|
|
||||||
uint8_t has_clip = context && context->clip_depth ? 1 : 0;
|
|
||||||
|
|
||||||
if (!context || !wr_valid_rect(rect) || !wr_valid_transform(transform))
|
|
||||||
return 0;
|
|
||||||
if (context->command_count == SIZE_MAX ||
|
|
||||||
context->command_count >= UINT32_MAX)
|
|
||||||
return 0;
|
|
||||||
if (!wr_reserve((void**)&context->commands, &context->command_capacity,
|
|
||||||
context->command_count + 1, sizeof(*context->commands)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
context->commands[context->command_count].rect = rect;
|
|
||||||
color = wr_normalize_color(color);
|
|
||||||
color.a *= context->opacity;
|
|
||||||
context->commands[context->command_count].color = color;
|
|
||||||
context->commands[context->command_count].transform = transform;
|
|
||||||
context->commands[context->command_count].clip_rect = clip_rect;
|
|
||||||
context->commands[context->command_count].has_clip = has_clip;
|
|
||||||
++context->command_count;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wr_frame*
|
|
||||||
wr_context_build_frame(wr_context* context)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!context)
|
|
||||||
return NULL;
|
|
||||||
context->quad_count = 0;
|
|
||||||
context->batch_count = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < context->command_count; ++i) {
|
|
||||||
wr_rect_command* command = &context->commands[i];
|
|
||||||
wr_gpu_quad* quad;
|
|
||||||
wr_gpu_batch* batch;
|
|
||||||
|
|
||||||
if (!wr_intersects(wr_transform_bounds(command->rect,
|
|
||||||
command->transform),
|
|
||||||
context->viewport) ||
|
|
||||||
(command->clip_rect.width <= 0.0f ||
|
|
||||||
command->clip_rect.height <= 0.0f))
|
|
||||||
continue;
|
|
||||||
if (context->quad_count == SIZE_MAX ||
|
|
||||||
context->quad_count >= UINT32_MAX ||
|
|
||||||
context->batch_count == SIZE_MAX ||
|
|
||||||
context->batch_count >= UINT32_MAX)
|
|
||||||
return NULL;
|
|
||||||
if (!wr_reserve((void**)&context->quads, &context->quad_capacity,
|
|
||||||
context->quad_count + 1, sizeof(*context->quads)) ||
|
|
||||||
!wr_reserve((void**)&context->batches, &context->batch_capacity,
|
|
||||||
context->batch_count + 1, sizeof(*context->batches)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
quad = &context->quads[context->quad_count++];
|
|
||||||
quad->rect = command->rect;
|
|
||||||
quad->color = command->color;
|
|
||||||
|
|
||||||
if (context->batch_count &&
|
|
||||||
wr_colors_equal(context->batches[context->batch_count - 1].color,
|
|
||||||
command->color) &&
|
|
||||||
context->batches[context->batch_count - 1].transform.m11 ==
|
|
||||||
command->transform.m11 &&
|
|
||||||
context->batches[context->batch_count - 1].transform.m12 ==
|
|
||||||
command->transform.m12 &&
|
|
||||||
context->batches[context->batch_count - 1].transform.m21 ==
|
|
||||||
command->transform.m21 &&
|
|
||||||
context->batches[context->batch_count - 1].transform.m22 ==
|
|
||||||
command->transform.m22 &&
|
|
||||||
context->batches[context->batch_count - 1].transform.m31 ==
|
|
||||||
command->transform.m31 &&
|
|
||||||
context->batches[context->batch_count - 1].transform.m32 ==
|
|
||||||
command->transform.m32 &&
|
|
||||||
context->batches[context->batch_count - 1].has_clip ==
|
|
||||||
command->has_clip &&
|
|
||||||
(!command->has_clip ||
|
|
||||||
wr_rects_equal(context->batches[context->batch_count - 1].clip_rect,
|
|
||||||
command->clip_rect))) {
|
|
||||||
batch = &context->batches[context->batch_count - 1];
|
|
||||||
++batch->quad_count;
|
|
||||||
} else {
|
|
||||||
batch = &context->batches[context->batch_count++];
|
|
||||||
batch->first_quad = (uint32_t)(context->quad_count - 1);
|
|
||||||
batch->quad_count = 1;
|
|
||||||
batch->color = command->color;
|
|
||||||
batch->transform = command->transform;
|
|
||||||
batch->clip_rect = command->clip_rect;
|
|
||||||
batch->has_clip = command->has_clip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context->frame.quads = context->quads;
|
|
||||||
context->frame.quad_count = context->quad_count;
|
|
||||||
context->frame.batches = context->batches;
|
|
||||||
context->frame.batch_count = context->batch_count;
|
|
||||||
return &context->frame;
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
#ifndef gfx_webrender_h
|
|
||||||
#define gfx_webrender_h
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct wr_context wr_context;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float width;
|
|
||||||
float height;
|
|
||||||
} wr_rect;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float r;
|
|
||||||
float g;
|
|
||||||
float b;
|
|
||||||
float a;
|
|
||||||
} wr_color;
|
|
||||||
|
|
||||||
/* A 2D affine transform in the same layout used by gfx::Matrix. */
|
|
||||||
typedef struct {
|
|
||||||
float m11;
|
|
||||||
float m12;
|
|
||||||
float m21;
|
|
||||||
float m22;
|
|
||||||
float m31;
|
|
||||||
float m32;
|
|
||||||
} wr_transform;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
wr_rect rect;
|
|
||||||
wr_color color;
|
|
||||||
} wr_gpu_quad;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t first_quad;
|
|
||||||
uint32_t quad_count;
|
|
||||||
wr_color color;
|
|
||||||
wr_transform transform;
|
|
||||||
wr_rect clip_rect;
|
|
||||||
uint8_t has_clip;
|
|
||||||
} wr_gpu_batch;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const wr_gpu_quad* quads;
|
|
||||||
size_t quad_count;
|
|
||||||
const wr_gpu_batch* batches;
|
|
||||||
size_t batch_count;
|
|
||||||
} wr_frame;
|
|
||||||
|
|
||||||
/* Creates a retained display-list context. */
|
|
||||||
wr_context* wr_context_create(size_t initial_capacity);
|
|
||||||
void wr_context_destroy(wr_context* context);
|
|
||||||
|
|
||||||
/* Removes every item from the retained display list. */
|
|
||||||
void wr_context_clear(wr_context* context);
|
|
||||||
|
|
||||||
/* Sets the viewport used for coarse CPU-side culling. */
|
|
||||||
void wr_context_set_viewport(wr_context* context, wr_rect viewport);
|
|
||||||
|
|
||||||
/* Sets the transform applied to subsequently recorded primitives. */
|
|
||||||
void wr_context_set_transform(wr_context* context, wr_transform transform);
|
|
||||||
|
|
||||||
/* Sets the opacity applied to subsequently recorded primitives. */
|
|
||||||
void wr_context_set_opacity(wr_context* context, float opacity);
|
|
||||||
|
|
||||||
/* Records a retained stacking-context boundary and restores it on pop. */
|
|
||||||
int wr_display_list_push_stacking_context(wr_context* context,
|
|
||||||
wr_transform transform,
|
|
||||||
float opacity);
|
|
||||||
void wr_display_list_pop_stacking_context(wr_context* context);
|
|
||||||
|
|
||||||
/* Pushes/pops a retained primitive clip. Clips are intersected in order. */
|
|
||||||
int wr_display_list_push_clip(wr_context* context, wr_rect clip);
|
|
||||||
void wr_display_list_pop_clip(wr_context* context);
|
|
||||||
|
|
||||||
/* Adds an opaque or translucent solid rectangle to the display list. */
|
|
||||||
int wr_display_list_push_rect(wr_context* context, wr_rect rect,
|
|
||||||
wr_color color);
|
|
||||||
|
|
||||||
/* Explicit transform form for display-list builders. */
|
|
||||||
int wr_display_list_push_transformed_rect(wr_context* context, wr_rect rect,
|
|
||||||
wr_color color,
|
|
||||||
wr_transform transform);
|
|
||||||
|
|
||||||
/* Builds the GPU-ready stream from the retained display list. */
|
|
||||||
const wr_frame* wr_context_build_frame(wr_context* context);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* gfx_webrender_h */
|
|
||||||
|
|
@ -727,9 +727,6 @@ pref("layout.scroll.root-frame-containers", false);
|
||||||
pref("gfx.layerscope.enabled", false);
|
pref("gfx.layerscope.enabled", false);
|
||||||
pref("gfx.layerscope.port", 23456);
|
pref("gfx.layerscope.port", 23456);
|
||||||
|
|
||||||
// Enable the incremental C WebRender path for supported compositor primitives.
|
|
||||||
pref("gfx.webrender.enabled", false);
|
|
||||||
|
|
||||||
// Log severe performance warnings to the error console and profiles.
|
// Log severe performance warnings to the error console and profiles.
|
||||||
// This should be use to quickly find which slow paths are used by test cases.
|
// This should be use to quickly find which slow paths are used by test cases.
|
||||||
pref("gfx.perf-warnings.enabled", false);
|
pref("gfx.perf-warnings.enabled", false);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue