Bug 1335799 - Update WR layers and FFI/bindings code for the webrender update. r=jrmuizel

MozReview-Commit-ID: Hv3MwSr97Op
This commit is contained in:
Nicolas Silva 2017-02-14 13:34:15 -05:00
Родитель edd715e334
Коммит f7a266bd62
20 изменённых файлов: 498 добавлений и 367 удалений

Просмотреть файл

@ -2614,7 +2614,7 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
LayerManager* lm = mPuppetWidget->GetLayerManager();
if (lm->AsWebRenderLayerManager()) {
lm->AsWebRenderLayerManager()->Initialize(compositorChild,
aLayersId,
wr::AsPipelineId(aLayersId),
&mTextureFactoryIdentifier);
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);

Просмотреть файл

@ -12,8 +12,6 @@ include protocol PTexture;
using WrBorderRadius from "mozilla/webrender/webrender_ffi.h";
using WrBorderSide from "mozilla/webrender/webrender_ffi.h";
using WrColor from "mozilla/webrender/webrender_ffi.h";
using WrImageKey from "mozilla/webrender/webrender_ffi.h";
using WrTextureFilter from "mozilla/webrender/webrender_ffi.h";
using WrLayoutSize from "mozilla/webrender/webrender_ffi.h";
using WrRect from "mozilla/webrender/webrender_ffi.h";
using WrGlyphArray from "mozilla/webrender/webrender_ffi.h";
@ -22,6 +20,8 @@ using MaybeImageMask from "mozilla/webrender/WebRenderTypes.h";
using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ImageRendering from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ImageKey from "mozilla/webrender/WebRenderTypes.h";
using mozilla::LayerIntRegion from "Units.h";
namespace mozilla {
@ -40,6 +40,15 @@ struct OpDPPushStackingContext {
struct OpDPPopStackingContext { };
struct OpDPPushScrollLayer {
WrRect bounds;
WrRect overflow;
MaybeImageMask mask;
uint64_t scrollid;
};
struct OpDPPopScrollLayer { };
struct OpDPPushRect {
WrRect bounds;
WrRect clip;
@ -60,8 +69,8 @@ struct OpDPPushImage {
WrRect bounds;
WrRect clip;
MaybeImageMask mask;
WrTextureFilter filter;
WrImageKey key;
ImageRendering filter;
ImageKey key;
};
struct OpDPPushExternalImageId {
@ -69,7 +78,7 @@ struct OpDPPushExternalImageId {
WrRect bounds;
WrRect clip;
MaybeImageMask mask;
WrTextureFilter filter;
ImageRendering filter;
uint64_t externalImageId;
};
@ -92,6 +101,8 @@ struct OpDPPushText {
union WebRenderCommand {
OpDPPushStackingContext;
OpDPPopStackingContext;
OpDPPushScrollLayer;
OpDPPopScrollLayer;
OpDPPushRect;
OpDPPushBorder;
OpDPPushImage;

Просмотреть файл

@ -150,7 +150,8 @@ WebRenderBridgeParent::RecvAddImage(const gfx::IntSize& aSize,
return IPC_OK();
}
MOZ_ASSERT(mApi);
*aOutImageKey = mApi->AddImageBuffer(aSize, aStride, aFormat,
wr::ImageDescriptor descriptor(aSize, aStride, aFormat);
*aOutImageKey = mApi->AddImageBuffer(descriptor,
aBuffer.AsSlice());
return IPC_OK();
@ -166,7 +167,8 @@ WebRenderBridgeParent::RecvUpdateImage(const wr::ImageKey& aImageKey,
return IPC_OK();
}
MOZ_ASSERT(mApi);
mApi->UpdateImageBuffer(aImageKey, aSize, aFormat, aBuffer.AsSlice());
wr::ImageDescriptor descriptor(aSize, aFormat);
mApi->UpdateImageBuffer(aImageKey, descriptor, aBuffer.AsSlice());
return IPC_OK();
}
@ -214,7 +216,7 @@ WebRenderBridgeParent::HandleDPEnd(InfallibleTArray<WebRenderCommand>&& aCommand
// to early-return from RecvDPEnd without doing so.
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
ProcessWebrenderCommands(aCommands, wr::Epoch(aTransactionId));
ProcessWebrenderCommands(aCommands, wr::NewEpoch(aTransactionId));
// The transaction ID might get reset to 1 if the page gets reloaded, see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
@ -264,6 +266,15 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
builder.PopStackingContext();
break;
}
case WebRenderCommand::TOpDPPushScrollLayer: {
const OpDPPushScrollLayer& op = cmd.get_OpDPPushScrollLayer();
builder.PushScrollLayer(op.bounds(), op.overflow(), op.mask().ptrOr(nullptr));
break;
}
case WebRenderCommand::TOpDPPopScrollLayer: {
builder.PopScrollLayer();
break;
}
case WebRenderCommand::TOpDPPushRect: {
const OpDPPushRect& op = cmd.get_OpDPPushRect();
builder.PushRect(op.bounds(), op.clip(), op.color());
@ -321,9 +332,10 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
break;
}
wr::ImageDescriptor descriptor(validRect.Size(), map.mStride, SurfaceFormat::B8G8R8A8);
wr::ImageKey key;
auto slice = Range<uint8_t>(map.mData, validRect.height * map.mStride);
key = mApi->AddImageBuffer(validRect.Size(), map.mStride, SurfaceFormat::B8G8R8A8, slice);
key = mApi->AddImageBuffer(descriptor, slice);
builder.PushImage(op.bounds(), op.clip(), op.mask().ptrOr(nullptr), op.filter(), key);
keysToDelete.push_back(key);
@ -379,7 +391,7 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
}
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(mPipelineId.mHandle, GetChildLayerObserverEpoch(), true);
mCompositorBridge->ObserveLayerUpdate(wr::AsUint64(mPipelineId), GetChildLayerObserverEpoch(), true);
}
}
@ -505,7 +517,7 @@ WebRenderBridgeParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverE
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvClearCachedResources()
{
mCompositorBridge->ObserveLayerUpdate(mPipelineId.mHandle, GetChildLayerObserverEpoch(), false);
mCompositorBridge->ObserveLayerUpdate(wr::AsUint64(mPipelineId), GetChildLayerObserverEpoch(), false);
return IPC_OK();
}

Просмотреть файл

@ -73,7 +73,7 @@ WebRenderCanvasLayer::RenderLayer()
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
Maybe<WrImageMask> mask = buildMaskLayer();
WrTextureFilter filter = (mSamplingFilter == gfx::SamplingFilter::POINT) ? WrTextureFilter::Point : WrTextureFilter::Linear;
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
if (gfxPrefs::LayersDump()) {

Просмотреть файл

@ -70,7 +70,7 @@ WebRenderRefLayer::RenderLayer()
Stringify(transform).c_str());
}
WrBridge()->AddWebRenderCommand(OpDPPushIframe(wr::ToWrRect(relBounds), wr::ToWrRect(relBounds), wr::PipelineId(mId)));
WrBridge()->AddWebRenderCommand(OpDPPushIframe(wr::ToWrRect(relBounds), wr::ToWrRect(relBounds), wr::AsPipelineId(mId)));
}
} // namespace layers

Просмотреть файл

@ -141,7 +141,7 @@ WebRenderImageLayer::RenderLayer()
Rect overflow(0, 0, relBounds.width, relBounds.height);
Matrix4x4 transform;// = GetTransform();
Maybe<WrImageMask> mask = buildMaskLayer();
WrTextureFilter filter = (mSamplingFilter == gfx::SamplingFilter::POINT) ? WrTextureFilter::Point : WrTextureFilter::Linear;
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
if (gfxPrefs::LayersDump()) {

Просмотреть файл

@ -117,7 +117,7 @@ WebRenderLayer::buildMaskLayer() {
wr::ImageKey maskKey;
WrBridge()->SendAddImage(size, map.GetStride(), SurfaceFormat::A8, buf, &maskKey);
imageMask.image = maskKey.mHandle;
imageMask.image = maskKey;
imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height));
imageMask.repeat = false;
WrManager()->AddImageKeyForDiscard(maskKey);
@ -195,14 +195,14 @@ WebRenderLayerManager::AsKnowsCompositor()
void
WebRenderLayerManager::Initialize(PCompositorBridgeChild* aCBChild,
uint64_t aLayersId,
wr::PipelineId aLayersId,
TextureFactoryIdentifier* aTextureFactoryIdentifier)
{
MOZ_ASSERT(mWrChild == nullptr);
MOZ_ASSERT(aTextureFactoryIdentifier);
TextureFactoryIdentifier textureFactoryIdentifier;
PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(wr::PipelineId(aLayersId),
PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(aLayersId,
&textureFactoryIdentifier);
MOZ_ASSERT(bridge);
mWrChild = static_cast<WebRenderBridgeChild*>(bridge);

Просмотреть файл

@ -65,7 +65,7 @@ class WebRenderLayerManager final : public LayerManager
public:
explicit WebRenderLayerManager(nsIWidget* aWidget);
void Initialize(PCompositorBridgeChild* aCBChild, uint64_t aLayersId, TextureFactoryIdentifier* aTextureFactoryIdentifier);
void Initialize(PCompositorBridgeChild* aCBChild, wr::PipelineId aLayersId, TextureFactoryIdentifier* aTextureFactoryIdentifier);
virtual void Destroy() override;

Просмотреть файл

@ -13,44 +13,44 @@ namespace mozilla {
namespace layers {
void
AppendToString(std::stringstream& aStream, WrMixBlendMode aMixBlendMode,
AppendToString(std::stringstream& aStream, wr::MixBlendMode aMixBlendMode,
const char* pfx, const char* sfx)
{
aStream << pfx;
switch (aMixBlendMode) {
case WrMixBlendMode::Normal:
aStream << "WrMixBlendMode::Normal"; break;
case WrMixBlendMode::Multiply:
aStream << "WrMixBlendMode::Multiply"; break;
case WrMixBlendMode::Screen:
aStream << "WrMixBlendMode::Screen"; break;
case WrMixBlendMode::Overlay:
aStream << "WrMixBlendMode::Overlay"; break;
case WrMixBlendMode::Darken:
aStream << "WrMixBlendMode::Darken"; break;
case WrMixBlendMode::Lighten:
aStream << "WrMixBlendMode::Lighten"; break;
case WrMixBlendMode::ColorDodge:
aStream << "WrMixBlendMode::ColorDodge"; break;
case WrMixBlendMode::ColorBurn:
aStream << "WrMixBlendMode::ColorBurn"; break;
case WrMixBlendMode::HardLight:
aStream << "WrMixBlendMode::HardLight"; break;
case WrMixBlendMode::SoftLight:
aStream << "WrMixBlendMode::SoftLight"; break;
case WrMixBlendMode::Difference:
aStream << "WrMixBlendMode::Difference"; break;
case WrMixBlendMode::Exclusion:
aStream << "WrMixBlendMode::Exclusion"; break;
case WrMixBlendMode::Hue:
aStream << "WrMixBlendMode::Hue"; break;
case WrMixBlendMode::Saturation:
aStream << "WrMixBlendMode::Saturation"; break;
case WrMixBlendMode::Color:
aStream << "WrMixBlendMode::Color"; break;
case WrMixBlendMode::Luminosity:
aStream << "WrMixBlendMode::Luminosity"; break;
case WrMixBlendMode::Sentinel:
case wr::MixBlendMode::Normal:
aStream << "wr::MixBlendMode::Normal"; break;
case wr::MixBlendMode::Multiply:
aStream << "wr::MixBlendMode::Multiply"; break;
case wr::MixBlendMode::Screen:
aStream << "wr::MixBlendMode::Screen"; break;
case wr::MixBlendMode::Overlay:
aStream << "wr::MixBlendMode::Overlay"; break;
case wr::MixBlendMode::Darken:
aStream << "wr::MixBlendMode::Darken"; break;
case wr::MixBlendMode::Lighten:
aStream << "wr::MixBlendMode::Lighten"; break;
case wr::MixBlendMode::ColorDodge:
aStream << "wr::MixBlendMode::ColorDodge"; break;
case wr::MixBlendMode::ColorBurn:
aStream << "wr::MixBlendMode::ColorBurn"; break;
case wr::MixBlendMode::HardLight:
aStream << "wr::MixBlendMode::HardLight"; break;
case wr::MixBlendMode::SoftLight:
aStream << "wr::MixBlendMode::SoftLight"; break;
case wr::MixBlendMode::Difference:
aStream << "wr::MixBlendMode::Difference"; break;
case wr::MixBlendMode::Exclusion:
aStream << "wr::MixBlendMode::Exclusion"; break;
case wr::MixBlendMode::Hue:
aStream << "wr::MixBlendMode::Hue"; break;
case wr::MixBlendMode::Saturation:
aStream << "wr::MixBlendMode::Saturation"; break;
case wr::MixBlendMode::Color:
aStream << "wr::MixBlendMode::Color"; break;
case wr::MixBlendMode::Luminosity:
aStream << "wr::MixBlendMode::Luminosity"; break;
case wr::MixBlendMode::Sentinel:
NS_ERROR("unknown mix blend mode");
aStream << "???";
}
@ -58,16 +58,18 @@ AppendToString(std::stringstream& aStream, WrMixBlendMode aMixBlendMode,
}
void
AppendToString(std::stringstream& aStream, WrTextureFilter aTextureFilter,
AppendToString(std::stringstream& aStream, wr::ImageRendering aTextureFilter,
const char* pfx, const char* sfx)
{
aStream << pfx;
switch (aTextureFilter) {
case WrTextureFilter::Linear:
aStream << "WrTextureFilter::Linear"; break;
case WrTextureFilter::Point:
aStream << "WrTextureFilter::Point"; break;
case WrTextureFilter::Sentinel:
case wr::ImageRendering::Auto:
aStream << "ImageRendering::Auto"; break;
case wr::ImageRendering::CrispEdges:
aStream << "ImageRendering::CrispEdges"; break;
case wr::ImageRendering::Pixelated:
aStream << "ImageRendering::Pixelated"; break;
case wr::ImageRendering::Sentinel:
NS_ERROR("unknown texture filter");
aStream << "???";
}

Просмотреть файл

@ -13,11 +13,11 @@ namespace mozilla {
namespace layers {
void
AppendToString(std::stringstream& aStream, WrMixBlendMode aMixBlendMode,
AppendToString(std::stringstream& aStream, wr::MixBlendMode aMixBlendMode,
const char* pfx="", const char* sfx="");
void
AppendToString(std::stringstream& aStream, WrTextureFilter aTextureFilter,
AppendToString(std::stringstream& aStream, wr::ImageRendering aTextureFilter,
const char* pfx="", const char* sfx="");
} // namespace layers

Просмотреть файл

@ -41,13 +41,15 @@ struct ParamTraits<mozilla::wr::ImageKey>
static void
Write(Message* aMsg, const mozilla::wr::ImageKey& aParam)
{
WriteParam(aMsg, aParam.mNamespace);
WriteParam(aMsg, aParam.mHandle);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::ImageKey* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mHandle);
return ReadParam(aMsg, aIter, &aResult->mNamespace)
&& ReadParam(aMsg, aIter, &aResult->mHandle);
}
};
@ -57,13 +59,15 @@ struct ParamTraits<mozilla::wr::FontKey>
static void
Write(Message* aMsg, const mozilla::wr::FontKey& aParam)
{
WriteParam(aMsg, aParam.mNamespace);
WriteParam(aMsg, aParam.mHandle);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::FontKey* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mHandle);
return ReadParam(aMsg, aIter, &aResult->mNamespace)
&& ReadParam(aMsg, aIter, &aResult->mHandle);
}
};
@ -73,13 +77,15 @@ struct ParamTraits<mozilla::wr::PipelineId>
static void
Write(Message* aMsg, const mozilla::wr::PipelineId& aParam)
{
WriteParam(aMsg, aParam.mNamespace);
WriteParam(aMsg, aParam.mHandle);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::PipelineId* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mHandle);
return ReadParam(aMsg, aIter, &aResult->mNamespace)
&& ReadParam(aMsg, aIter, &aResult->mHandle);
}
};
@ -286,11 +292,11 @@ struct ParamTraits<WrImageMask>
};
template<>
struct ParamTraits<WrTextureFilter>
struct ParamTraits<WrImageRendering>
: public ContiguousEnumSerializer<
WrTextureFilter,
WrTextureFilter::Linear,
WrTextureFilter::Sentinel>
WrImageRendering,
WrImageRendering::Auto,
WrImageRendering::Sentinel>
{
};

Просмотреть файл

@ -167,7 +167,7 @@ WebRenderPaintedLayer::RenderLayer()
transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID));
WrBridge()->AddWebRenderCommand(OpDPPushExternalImageId(visibleRegion, wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), WrTextureFilter::Linear, mExternalImageId));
WrBridge()->AddWebRenderCommand(OpDPPushExternalImageId(visibleRegion, wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), wr::ImageRendering::Auto, mExternalImageId));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
}

Просмотреть файл

@ -5,7 +5,7 @@ authors = ["The Mozilla Project Developers"]
license = "MPL-2.0"
[dependencies]
webrender_traits = {path = "../webrender_traits", version = "0.11.0"}
webrender_traits = {path = "../webrender_traits", version = "0.14"}
euclid = "0.10"
app_units = "0.3"
gleam = "0.2"
@ -13,7 +13,7 @@ fnv="1.0"
[dependencies.webrender]
path = "../webrender"
version = "0.11.0"
version = "0.15"
default-features = false
features = ["codegen"]

Просмотреть файл

@ -136,20 +136,6 @@ RenderThread::NewScrollFrameReady(wr::WindowId aWindowId, bool aCompositeNeeded)
UpdateAndRender(aWindowId);
}
void
RenderThread::PipelineSizeChanged(wr::WindowId aWindowId, uint64_t aPipelineId, float aWidth, float aHeight)
{
if (!IsInRenderThread()) {
Loop()->PostTask(NewRunnableMethod<wr::WindowId, uint64_t, float, float>(
this, &RenderThread::PipelineSizeChanged,
aWindowId, aPipelineId, aWidth, aHeight
));
return;
}
UpdateAndRender(aWindowId);
}
void
RenderThread::RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aEvent)
{
@ -177,7 +163,7 @@ NotifyDidRender(layers::CompositorBridgeParentBase* aBridge,
// TODO - Currently each bridge seems to only have one pipeline but at some
// point we should pass make sure we only notify bridges that have the
// corresponding pipeline id.
aBridge->NotifyDidComposite(epoch, aStart, aEnd);
aBridge->NotifyDidComposite(epoch.mHandle, aStart, aEnd);
}
wr_rendered_epochs_delete(aEpochs);
}
@ -227,15 +213,6 @@ void wr_notifier_new_scroll_frame_ready(WrWindowId aWindowId, bool aCompositeNee
aCompositeNeeded);
}
void wr_notifier_pipeline_size_changed(WrWindowId aWindowId,
uint64_t aPipelineId,
float aWidth,
float aHeight)
{
mozilla::wr::RenderThread::Get()->PipelineSizeChanged(mozilla::wr::WindowId(aWindowId),
aPipelineId, aWidth, aHeight);
}
void wr_notifier_external_event(WrWindowId aWindowId, size_t aRawEvent)
{
mozilla::UniquePtr<mozilla::wr::RendererEvent> evt(

Просмотреть файл

@ -13,25 +13,6 @@
namespace mozilla {
namespace wr {
Maybe<WrImageFormat>
SurfaceFormatToWrImageFormat(gfx::SurfaceFormat aFormat) {
switch (aFormat) {
case gfx::SurfaceFormat::B8G8R8X8:
// TODO: WebRender will have a BGRA + opaque flag for this but does not
// have it yet (cf. issue #732).
case gfx::SurfaceFormat::B8G8R8A8:
return Some(WrImageFormat::RGBA8);
case gfx::SurfaceFormat::B8G8R8:
return Some(WrImageFormat::RGB8);
case gfx::SurfaceFormat::A8:
return Some(WrImageFormat::A8);
case gfx::SurfaceFormat::UNKNOWN:
return Some(WrImageFormat::Invalid);
default:
return Nothing();
}
}
class NewRenderer : public RendererEvent
{
public:
@ -69,7 +50,9 @@ public:
wr_gl_init(gl.get());
WrRenderer* wrRenderer = nullptr;
wr_window_new(aWindowId.mHandle, this->mEnableProfiler, mWrApi, &wrRenderer);
if (!wr_window_new(aWindowId, this->mEnableProfiler, mWrApi, &wrRenderer)) {
return;
}
MOZ_ASSERT(wrRenderer);
RefPtr<RenderThread> thread = &aRenderThread;
@ -127,7 +110,7 @@ WebRenderAPI::Create(bool aEnableProfiler,
MOZ_ASSERT(aWidget);
static uint64_t sNextId = 1;
WindowId id(sNextId++);
auto id = NewWindowId(sNextId++);
WrAPI* wrApi = nullptr;
GLint maxTextureSize = 0;
@ -166,7 +149,7 @@ WebRenderAPI::SetRootDisplayList(gfx::Color aBgColor,
DisplayListBuilder& aBuilder)
{
wr_api_set_root_display_list(mWrApi, aBuilder.mWrState,
aEpoch.mHandle,
aEpoch,
aViewportSize.width, aViewportSize.height);
}
@ -216,19 +199,15 @@ WebRenderAPI::Readback(gfx::IntSize size,
void
WebRenderAPI::SetRootPipeline(PipelineId aPipeline)
{
wr_api_set_root_pipeline(mWrApi, aPipeline.mHandle);
wr_api_set_root_pipeline(mWrApi, aPipeline);
}
ImageKey
WebRenderAPI::AddImageBuffer(gfx::IntSize aSize,
uint32_t aStride,
gfx::SurfaceFormat aFormat,
WebRenderAPI::AddImageBuffer(const ImageDescriptor& aDescritptor,
Range<uint8_t> aBytes)
{
auto format = SurfaceFormatToWrImageFormat(aFormat).value();
return ImageKey(wr_api_add_image(mWrApi,
aSize.width, aSize.height,
aStride, format,
&aDescritptor,
&aBytes[0], aBytes.length()));
}
@ -245,21 +224,19 @@ WebRenderAPI::AddExternalImageHandle(gfx::IntSize aSize,
void
WebRenderAPI::UpdateImageBuffer(ImageKey aKey,
gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
const ImageDescriptor& aDescritptor,
Range<uint8_t> aBytes)
{
auto format = SurfaceFormatToWrImageFormat(aFormat).value();
wr_api_update_image(mWrApi,
aKey.mHandle,
aSize.width, aSize.height, format,
aKey,
&aDescritptor,
&aBytes[0], aBytes.length());
}
void
WebRenderAPI::DeleteImage(ImageKey aKey)
{
wr_api_delete_image(mWrApi, aKey.mHandle);
wr_api_delete_image(mWrApi, aKey);
}
wr::FontKey
@ -317,7 +294,7 @@ WebRenderAPI::RunOnRenderThread(UniquePtr<RendererEvent> aEvent)
DisplayListBuilder::DisplayListBuilder(const LayerIntSize& aSize, PipelineId aId)
{
MOZ_COUNT_CTOR(DisplayListBuilder);
mWrState = wr_state_new(aSize.width, aSize.height, aId.mHandle);
mWrState = wr_state_new(aSize.width, aSize.height, aId);
}
DisplayListBuilder::~DisplayListBuilder()
@ -335,7 +312,7 @@ DisplayListBuilder::Begin(const LayerIntSize& aSize)
void
DisplayListBuilder::End(WebRenderAPI& aApi, Epoch aEpoch)
{
wr_dp_end(mWrState, aApi.mWrApi, aEpoch.mHandle);
wr_dp_end(mWrState, aApi.mWrApi, aEpoch);
}
void
@ -356,6 +333,20 @@ DisplayListBuilder::PopStackingContext()
wr_dp_pop_stacking_context(mWrState);
}
void
DisplayListBuilder::PushScrollLayer(const WrRect& aBounds,
const WrRect& aOverflow,
const WrImageMask* aMask)
{
wr_dp_push_scroll_layer(mWrState, aBounds, aOverflow, aMask);
}
void
DisplayListBuilder::PopScrollLayer()
{
wr_dp_pop_scroll_layer(mWrState);
}
void
DisplayListBuilder::PushRect(const WrRect& aBounds,
const WrRect& aClip,
@ -368,10 +359,10 @@ void
DisplayListBuilder::PushImage(const WrRect& aBounds,
const WrRect& aClip,
const WrImageMask* aMask,
const WrTextureFilter aFilter,
wr::ImageRendering aFilter,
wr::ImageKey aImage)
{
wr_dp_push_image(mWrState, aBounds, aClip, aMask, aFilter, aImage.mHandle);
wr_dp_push_image(mWrState, aBounds, aClip, aMask, aFilter, aImage);
}
void
@ -379,7 +370,7 @@ DisplayListBuilder::PushIFrame(const WrRect& aBounds,
const WrRect& aClip,
PipelineId aPipeline)
{
wr_dp_push_iframe(mWrState, aBounds, aClip, aPipeline.mHandle);
wr_dp_push_iframe(mWrState, aBounds, aClip, aPipeline);
}
void
@ -406,7 +397,7 @@ DisplayListBuilder::PushText(const WrRect& aBounds,
{
wr_dp_push_text(mWrState, aBounds, aClip,
ToWrColor(aColor),
aFontKey.mHandle,
aFontKey,
&aGlyphBuffer[0], aGlyphBuffer.length(),
aGlyphSize);
}

Просмотреть файл

@ -48,9 +48,7 @@ public:
void SetRootPipeline(wr::PipelineId aPipeline);
wr::ImageKey AddImageBuffer(gfx::IntSize aSize,
uint32_t aStride,
gfx::SurfaceFormat aFormat,
wr::ImageKey AddImageBuffer(const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes);
wr::ImageKey AddExternalImageHandle(gfx::IntSize aSize,
@ -58,8 +56,7 @@ public:
uint64_t aHandle);
void UpdateImageBuffer(wr::ImageKey aKey,
gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes);
void DeleteImage(wr::ImageKey aKey);
@ -114,6 +111,13 @@ public:
void PopStackingContext();
void PushScrollLayer(const WrRect& aBounds, // TODO: We should work with strongly typed rects
const WrRect& aOverflow,
const WrImageMask* aMask); // TODO: needs a wrapper.
void PopScrollLayer();
void PushRect(const WrRect& aBounds,
const WrRect& aClip,
const WrColor& aColor);
@ -121,7 +125,7 @@ public:
void PushImage(const WrRect& aBounds,
const WrRect& aClip,
const WrImageMask* aMask,
const WrTextureFilter aFilter,
wr::ImageRendering aFilter,
wr::ImageKey aImage);
void PushIFrame(const WrRect& aBounds,

Просмотреть файл

@ -9,48 +9,128 @@
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/Maybe.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/gfx/Tools.h"
typedef mozilla::Maybe<WrImageMask> MaybeImageMask;
namespace mozilla {
namespace wr {
static inline WrMixBlendMode ToWrMixBlendMode(gfx::CompositionOp compositionOp)
typedef WrMixBlendMode MixBlendMode;
typedef WrImageRendering ImageRendering;
typedef WrImageFormat ImageFormat;
typedef WrWindowId WindowId;
typedef WrPipelineId PipelineId;
typedef WrImageKey ImageKey;
typedef WrFontKey FontKey;
typedef WrEpoch Epoch;
inline WindowId NewWindowId(uint64_t aId) {
WindowId id;
id.mHandle = aId;
return id;
}
inline Epoch NewEpoch(uint32_t aEpoch) {
Epoch e;
e.mHandle = aEpoch;
return e;
}
inline Maybe<WrImageFormat>
SurfaceFormatToWrImageFormat(gfx::SurfaceFormat aFormat) {
switch (aFormat) {
case gfx::SurfaceFormat::B8G8R8X8:
// TODO: WebRender will have a BGRA + opaque flag for this but does not
// have it yet (cf. issue #732).
case gfx::SurfaceFormat::B8G8R8A8:
return Some(WrImageFormat::RGBA8);
case gfx::SurfaceFormat::B8G8R8:
return Some(WrImageFormat::RGB8);
case gfx::SurfaceFormat::A8:
return Some(WrImageFormat::A8);
case gfx::SurfaceFormat::UNKNOWN:
return Some(WrImageFormat::Invalid);
default:
return Nothing();
}
}
struct ImageDescriptor: public WrImageDescriptor {
ImageDescriptor(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat)
{
format = SurfaceFormatToWrImageFormat(aFormat).value();
width = aSize.width;
height = aSize.height;
stride = 0;
is_opaque = gfx::IsOpaqueFormat(aFormat);
}
ImageDescriptor(const gfx::IntSize& aSize, uint32_t aByteStride, gfx::SurfaceFormat aFormat)
{
format = SurfaceFormatToWrImageFormat(aFormat).value();
width = aSize.width;
height = aSize.height;
stride = aByteStride;
is_opaque = gfx::IsOpaqueFormat(aFormat);
}
};
// Whenever possible, use wr::PipelineId instead of manipulating uint64_t.
inline uint64_t AsUint64(const PipelineId& aId) {
return (static_cast<uint64_t>(aId.mNamespace) << 32)
+ static_cast<uint64_t>(aId.mHandle);
}
inline PipelineId AsPipelineId(const uint64_t& aId) {
PipelineId pipeline;
pipeline.mNamespace = aId >> 32;
pipeline.mHandle = aId;
return pipeline;
}
inline ImageRendering ToImageRendering(gfx::SamplingFilter aFilter)
{
return aFilter == gfx::SamplingFilter::POINT ? ImageRendering::Pixelated
: ImageRendering::Auto;
}
static inline MixBlendMode ToWrMixBlendMode(gfx::CompositionOp compositionOp)
{
switch (compositionOp)
{
case gfx::CompositionOp::OP_MULTIPLY:
return WrMixBlendMode::Multiply;
return MixBlendMode::Multiply;
case gfx::CompositionOp::OP_SCREEN:
return WrMixBlendMode::Screen;
return MixBlendMode::Screen;
case gfx::CompositionOp::OP_OVERLAY:
return WrMixBlendMode::Overlay;
return MixBlendMode::Overlay;
case gfx::CompositionOp::OP_DARKEN:
return WrMixBlendMode::Darken;
return MixBlendMode::Darken;
case gfx::CompositionOp::OP_LIGHTEN:
return WrMixBlendMode::Lighten;
return MixBlendMode::Lighten;
case gfx::CompositionOp::OP_COLOR_DODGE:
return WrMixBlendMode::ColorDodge;
return MixBlendMode::ColorDodge;
case gfx::CompositionOp::OP_COLOR_BURN:
return WrMixBlendMode::ColorBurn;
return MixBlendMode::ColorBurn;
case gfx::CompositionOp::OP_HARD_LIGHT:
return WrMixBlendMode::HardLight;
return MixBlendMode::HardLight;
case gfx::CompositionOp::OP_SOFT_LIGHT:
return WrMixBlendMode::SoftLight;
return MixBlendMode::SoftLight;
case gfx::CompositionOp::OP_DIFFERENCE:
return WrMixBlendMode::Difference;
return MixBlendMode::Difference;
case gfx::CompositionOp::OP_EXCLUSION:
return WrMixBlendMode::Exclusion;
return MixBlendMode::Exclusion;
case gfx::CompositionOp::OP_HUE:
return WrMixBlendMode::Hue;
return MixBlendMode::Hue;
case gfx::CompositionOp::OP_SATURATION:
return WrMixBlendMode::Saturation;
return MixBlendMode::Saturation;
case gfx::CompositionOp::OP_COLOR:
return WrMixBlendMode::Color;
return MixBlendMode::Color;
case gfx::CompositionOp::OP_LUMINOSITY:
return WrMixBlendMode::Luminosity;
return MixBlendMode::Luminosity;
default:
return WrMixBlendMode::Normal;
return MixBlendMode::Normal;
}
}
@ -186,53 +266,6 @@ struct ByteBuffer
bool mOwned;
};
struct WindowId {
explicit WindowId(WrWindowId aHandle) : mHandle(aHandle) {}
WindowId() : mHandle(0) {}
bool operator<(const WindowId& aOther) const { return mHandle < aOther.mHandle; }
bool operator==(const WindowId& aOther) const { return mHandle == aOther.mHandle; }
WrWindowId mHandle;
};
struct PipelineId {
explicit PipelineId(WrPipelineId aHandle) : mHandle(aHandle) {}
PipelineId() : mHandle(0) {}
bool operator<(const PipelineId& aOther) const { return mHandle < aOther.mHandle; }
bool operator==(const PipelineId& aOther) const { return mHandle == aOther.mHandle; }
WrPipelineId mHandle;
};
// TODO: We need to merge this with the notion of transaction id.
struct Epoch {
explicit Epoch(WrEpoch aHandle) : mHandle(aHandle) {}
Epoch() : mHandle(0) {}
bool operator<(const Epoch& aOther) const { return mHandle < aOther.mHandle; }
bool operator==(const Epoch& aOther) const { return mHandle == aOther.mHandle; }
WrEpoch mHandle;
};
struct FontKey {
explicit FontKey(WrFontKey aHandle) : mHandle(aHandle) {}
FontKey() : mHandle(0) {}
bool operator<(const FontKey& aOther) const { return mHandle < aOther.mHandle; }
bool operator==(const FontKey& aOther) const { return mHandle == aOther.mHandle; }
WrFontKey mHandle;
};
struct ImageKey {
explicit ImageKey(WrImageKey aHandle) : mHandle(aHandle) {}
ImageKey() : mHandle(0) {}
bool operator<(const ImageKey& aOther) const { return mHandle < aOther.mHandle; }
bool operator==(const ImageKey& aOther) const { return mHandle == aOther.mHandle; }
WrImageKey mHandle;
};
} // namespace wr
} // namespace mozilla

Просмотреть файл

@ -3,23 +3,60 @@ use std::{mem, slice};
use std::os::raw::{c_void, c_char};
use gleam::gl;
use webrender_traits::{BorderSide, BorderStyle, BorderRadius};
use webrender_traits::{PipelineId, ClipRegion};
use webrender_traits::{PipelineId, ClipRegion, PropertyBinding};
use webrender_traits::{Epoch, ColorF, GlyphInstance, ImageDescriptor};
use webrender_traits::{FilterOp, ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering, RendererKind, MixBlendMode};
use webrender_traits::{ExternalImageId, RenderApi, FontKey};
use webrender_traits::{DeviceUintSize, ExternalEvent};
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform};
use webrender_traits::ServoScrollRootId;
use webrender::renderer::{Renderer, RendererOptions};
use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource};
use app_units::Au;
extern crate webrender_traits;
fn pipeline_id_to_u64(id: PipelineId) -> u64 { ((id.0 as u64) << 32) + id.1 as u64 }
fn u64_to_pipeline_id(id: u64) -> PipelineId { PipelineId((id >> 32) as u32, id as u32) }
// This macro adds some checks to make sure we notice when the memory representation of
// types change.
macro_rules! check_ffi_type {
($check_sizes_match:ident struct $TypeName:ident as ($T1:ident, $T2:ident)) => (
fn $check_sizes_match() {
#[repr(C)] struct TestType($T1, $T2);
let _ = mem::transmute::<$TypeName, TestType>;
}
);
($check_sizes_match:ident struct $TypeName:ident as ($T:ident)) => (
fn $check_sizes_match() {
#[repr(C)] struct TestType($T);
let _ = mem::transmute::<$TypeName, TestType>;
}
);
($check_sizes_match:ident enum $TypeName:ident as $T:ident) => (
fn $check_sizes_match() { let _ = mem::transmute::<$TypeName, $T>; }
);
}
check_ffi_type!(_pipeline_id_repr struct PipelineId as (u32, u32));
check_ffi_type!(_image_key_repr struct ImageKey as (u32, u32));
check_ffi_type!(_font_key_repr struct FontKey as (u32, u32));
check_ffi_type!(_epoch_repr struct Epoch as (u32));
check_ffi_type!(_image_format_repr enum ImageFormat as u32);
check_ffi_type!(_border_style_repr enum BorderStyle as u32);
check_ffi_type!(_image_rendering_repr enum ImageRendering as u32);
fn font_key_to_u64(key: FontKey) -> u64 { unsafe { mem::transmute(key) } }
fn u64_to_font_key(key: u64) -> FontKey { unsafe { mem::transmute(key) } }
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct WrWindowId(u64);
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct WrImageDescriptor {
pub format: ImageFormat,
pub width: u32,
pub height: u32,
pub stride: u32,
pub is_opaque: bool,
}
fn get_proc_address(glcontext_ptr: *mut c_void, name: &str) -> *const c_void{
@ -109,18 +146,23 @@ pub unsafe extern fn wr_api_set_root_display_list(api: &mut RenderApi,
let root_background_color = ColorF::new(0.3, 0.0, 0.0, 1.0);
let frame_builder = mem::replace(&mut state.frame_builder,
WebRenderFrameBuilder::new(state.pipeline_id));
// See the documentation of set_root_display_list in api.rs. I don't think
// it makes a difference in gecko at the moment(until APZ is figured out)
// but I suppose it is a good default.
let preserve_frame_state = true;
//let (dl_builder, aux_builder) = fb.dl_builder.finalize();
api.set_root_display_list(Some(root_background_color),
epoch,
LayoutSize::new(viewport_width, viewport_height),
frame_builder.dl_builder);
api.generate_frame();
frame_builder.dl_builder,
preserve_frame_state);
api.generate_frame(None);
}
#[no_mangle]
pub extern fn wr_window_new(window_id: u64,
pub extern fn wr_window_new(window_id: WrWindowId,
enable_profiler: bool,
out_api: &mut *mut RenderApi,
out_renderer: &mut *mut Renderer) {
out_renderer: &mut *mut Renderer) -> bool {
assert!(unsafe { is_in_render_thread() });
let opts = RendererOptions {
@ -129,7 +171,6 @@ pub extern fn wr_window_new(window_id: u64,
enable_aa: false,
enable_subpixel_aa: false,
enable_profiler: enable_profiler,
enable_recording: false,
enable_scrollbars: false,
precache_shaders: false,
renderer_kind: RendererKind::Native,
@ -137,13 +178,24 @@ pub extern fn wr_window_new(window_id: u64,
clear_framebuffer: true,
render_target_debug: false,
clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0),
recorder: None,
workers: None,
};
let (renderer, sender) = match Renderer::new(opts) {
Ok((renderer, sender)) => { (renderer, sender) }
Err(e) => {
println!(" Failed to create a Renderer: {:?}", e);
return false;
}
};
let (renderer, sender) = Renderer::new(opts);
renderer.set_render_notifier(Box::new(CppNotifier { window_id: window_id }));
*out_api = Box::into_raw(Box::new(sender.create_api()));
*out_renderer = Box::into_raw(Box::new(renderer));
return true;
}
// Call MakeCurrent before this.
@ -160,9 +212,8 @@ pub extern fn wr_gl_init(gl_context: *mut c_void) {
}
#[no_mangle]
pub extern fn wr_state_new(width: u32, height: u32, pipeline: u64) -> *mut WrState {
pub extern fn wr_state_new(width: u32, height: u32, pipeline_id: PipelineId) -> *mut WrState {
assert!(unsafe { is_in_compositor_thread() });
let pipeline_id = u64_to_pipeline_id(pipeline);
let state = Box::new(WrState {
size: (width, height),
@ -197,8 +248,8 @@ pub extern fn wr_dp_begin(state: &mut WrState, width: u32, height: u32) {
bounds,
ClipRegion::simple(&bounds),
0,
&LayoutTransform::identity(),
&LayoutTransform::identity(),
PropertyBinding::Value(LayoutTransform::identity()),
LayoutTransform::identity(),
webrender_traits::MixBlendMode::Normal,
Vec::new(),
);
@ -215,11 +266,13 @@ pub extern fn wr_dp_end(state: &mut WrState, api: &mut RenderApi, epoch: u32) {
let fb = mem::replace(&mut state.frame_builder, WebRenderFrameBuilder::new(pipeline_id));
let preserve_frame_state = true;
api.set_root_display_list(Some(root_background_color),
Epoch(epoch),
LayoutSize::new(width as f32, height as f32),
fb.dl_builder);
api.generate_frame();
fb.dl_builder,
preserve_frame_state);
api.generate_frame(None);
}
#[no_mangle]
@ -231,11 +284,11 @@ pub unsafe extern fn wr_renderer_flush_rendered_epochs(renderer: &mut Renderer)
#[no_mangle]
pub unsafe extern fn wr_rendered_epochs_next(pipeline_epochs: &mut Vec<(PipelineId, Epoch)>,
out_pipeline: &mut u64,
out_epoch: &mut u32) -> bool {
out_pipeline: &mut PipelineId,
out_epoch: &mut Epoch) -> bool {
if let Some((pipeline, epoch)) = pipeline_epochs.pop() {
*out_pipeline = mem::transmute(pipeline);
*out_epoch = mem::transmute(epoch);
*out_pipeline = pipeline;
*out_epoch = epoch;
return true;
}
return false;
@ -248,16 +301,15 @@ pub unsafe extern fn wr_rendered_epochs_delete(pipeline_epochs: *mut Vec<(Pipeli
struct CppNotifier {
window_id: u64,
window_id: WrWindowId,
}
unsafe impl Send for CppNotifier {}
extern {
fn wr_notifier_new_frame_ready(window_id: u64);
fn wr_notifier_new_scroll_frame_ready(window_id: u64, composite_needed: bool);
fn wr_notifier_pipeline_size_changed(window_id: u64, pipeline: u64, new_width: f32, new_height: f32);
fn wr_notifier_external_event(window_id: u64, raw_event: usize);
fn wr_notifier_new_frame_ready(window_id: WrWindowId);
fn wr_notifier_new_scroll_frame_ready(window_id: WrWindowId, composite_needed: bool);
fn wr_notifier_external_event(window_id: WrWindowId, raw_event: usize);
}
impl webrender_traits::RenderNotifier for CppNotifier {
@ -273,20 +325,6 @@ impl webrender_traits::RenderNotifier for CppNotifier {
}
}
fn pipeline_size_changed(&mut self,
pipeline_id: PipelineId,
new_size: Option<LayoutSize>) {
let (w, h) = if let Some(size) = new_size {
(size.width, size.height)
} else {
(0.0, 0.0)
};
unsafe {
let id = pipeline_id_to_u64(pipeline_id);
wr_notifier_pipeline_size_changed(self.window_id, id, w, h);
}
}
fn external_event(&mut self, event: ExternalEvent) {
unsafe {
wr_notifier_external_event(self.window_id, event.unwrap());
@ -443,26 +481,29 @@ pub extern fn wr_dp_push_stacking_context(state:&mut WrState, bounds: WrRect, ov
state.z_index += 1;
let bounds = bounds.to_rect();
let overflow = overflow.to_rect();
let mut overflow = overflow.to_rect();
let mix_blend_mode = mix_blend_mode.to_mix_blend_mode();
//println!("stacking context: {:?} {:?} {:?} {:?} {:?}", state.pipeline_id, bounds, overflow, mask, transform);
// convert from the C type to the Rust type
let mask = unsafe { mask.as_ref().map(|&WrImageMask{image, ref rect,repeat}| ImageMask{image: image, rect: rect.to_rect(), repeat: repeat}) };
let clip_region2 = state.frame_builder.dl_builder.new_clip_region(&overflow, vec![], None);
let clip_region = state.frame_builder.dl_builder.new_clip_region(&overflow, vec![], mask);
let mut filters: Vec<FilterOp> = Vec::new();
if opacity < 1.0 {
filters.push(FilterOp::Opacity(opacity));
filters.push(FilterOp::Opacity(PropertyBinding::Value(opacity)));
}
state.frame_builder.dl_builder.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
bounds,
clip_region,
clip_region2,
state.z_index,
transform,
&LayoutTransform::identity(),
PropertyBinding::Value(*transform),
LayoutTransform::identity(),
mix_blend_mode,
filters);
state.frame_builder.dl_builder.push_scroll_layer(clip_region, bounds.size, ServoScrollRootId(1));
}
@ -470,38 +511,73 @@ pub extern fn wr_dp_push_stacking_context(state:&mut WrState, bounds: WrRect, ov
pub extern fn wr_dp_pop_stacking_context(state: &mut WrState)
{
assert!( unsafe { is_in_compositor_thread() });
state.frame_builder.dl_builder.pop_stacking_context()
state.frame_builder.dl_builder.pop_scroll_layer();
state.frame_builder.dl_builder.pop_stacking_context();
//println!("pop_stacking {:?}", state.pipeline_id);
}
#[no_mangle]
pub extern fn wr_api_set_root_pipeline(api: &mut RenderApi, pipeline_id: u64) {
api.set_root_pipeline(u64_to_pipeline_id(pipeline_id));
api.generate_frame();
pub extern fn wr_dp_push_scroll_layer(state: &mut WrState, bounds: WrRect, overflow: WrRect, mask: Option<&WrImageMask>)
{
let bounds = bounds.to_rect();
let overflow = overflow.to_rect();
let mask = mask.map(|&WrImageMask{image, ref rect,repeat}| ImageMask{image: image, rect: rect.to_rect(), repeat: repeat});
let clip_region = state.frame_builder.dl_builder.new_clip_region(&overflow, vec![], mask);
state.frame_builder.dl_builder.push_scroll_layer(clip_region, bounds.size, ServoScrollRootId(1));
}
#[no_mangle]
pub extern fn wr_api_add_image(api: &mut RenderApi, width: u32, height: u32, stride: u32, format: ImageFormat, bytes: * const u8, size: usize) -> ImageKey {
pub extern fn wr_dp_pop_scroll_layer(state: &mut WrState)
{
assert!( unsafe { is_in_compositor_thread() });
state.frame_builder.dl_builder.pop_scroll_layer();
}
#[no_mangle]
pub extern fn wr_api_set_root_pipeline(api: &mut RenderApi, pipeline_id: PipelineId) {
api.set_root_pipeline(pipeline_id);
api.generate_frame(None);
}
#[no_mangle]
pub extern fn wr_api_add_image(api: &mut RenderApi, descriptor: &WrImageDescriptor, bytes: * const u8, size: usize) -> ImageKey {
assert!( unsafe { is_in_compositor_thread() });
let bytes = unsafe { slice::from_raw_parts(bytes, size).to_owned() };
let stride_option = match stride {
0 => None,
_ => Some(stride),
};
api.add_image(ImageDescriptor{width: width, height: height, stride: stride_option, format: format, is_opaque: false}, ImageData::new(bytes))
return api.add_image(
ImageDescriptor {
width: descriptor.width,
height: descriptor.height,
stride: if descriptor.stride != 0 { Some(descriptor.stride) } else { None },
format: descriptor.format,
is_opaque: descriptor.is_opaque,
},
ImageData::new(bytes)
);
}
#[no_mangle]
pub extern fn wr_api_add_external_image_texture(api: &mut RenderApi, width: u32, height: u32, format: ImageFormat, external_image_id: u64) -> ImageKey {
assert!( unsafe { is_in_compositor_thread() });
api.add_image(ImageDescriptor{width:width, height:height, stride:None, format: format, is_opaque: false}, ImageData::External(ExternalImageId(external_image_id)))
unimplemented!(); // TODO
//api.add_image(ImageDescriptor{width:width, height:height, stride:None, format: format, is_opaque: false}, ImageData::External(ExternalImageId(external_image_id)))
}
#[no_mangle]
pub extern fn wr_api_update_image(api: &mut RenderApi, key: ImageKey, width: u32, height: u32, format: ImageFormat, bytes: * const u8, size: usize) {
pub extern fn wr_api_update_image(api: &mut RenderApi, key: ImageKey, descriptor: &WrImageDescriptor, bytes: * const u8, size: usize) {
assert!( unsafe { is_in_compositor_thread() });
let bytes = unsafe { slice::from_raw_parts(bytes, size).to_owned() };
api.update_image(key, ImageDescriptor{width:width, height:height, stride:None, format:format, is_opaque: false}, bytes);
api.update_image(
key,
ImageDescriptor {
width: descriptor.width,
height: descriptor.height,
stride: if descriptor.stride != 0 { Some(descriptor.stride) } else { None },
format: descriptor.format,
is_opaque: descriptor.is_opaque,
},
bytes
);
}
#[no_mangle]
pub extern fn wr_api_delete_image(api: &mut RenderApi, key: ImageKey) {
@ -545,13 +621,12 @@ pub extern fn wr_dp_push_border(state: &mut WrState, rect: WrRect, clip: WrRect,
}
#[no_mangle]
pub extern fn wr_dp_push_iframe(state: &mut WrState, rect: WrRect, clip: WrRect, layers_id: u64) {
pub extern fn wr_dp_push_iframe(state: &mut WrState, rect: WrRect, clip: WrRect, pipeline_id: PipelineId) {
assert!( unsafe { is_in_compositor_thread() });
let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(),
Vec::new(),
None);
let pipeline_id = u64_to_pipeline_id(layers_id);
state.frame_builder.dl_builder.push_iframe(rect.to_rect(),
clip_region,
pipeline_id);
@ -657,34 +732,17 @@ impl WrImageMask
}
}
#[repr(C)]
pub enum WrTextureFilter
{
Linear,
Point,
}
impl WrTextureFilter
{
pub fn to_image_rendering(self) -> ImageRendering
{
match self
{
WrTextureFilter::Linear => ImageRendering::Auto,
WrTextureFilter::Point => ImageRendering::Pixelated,
}
}
}
#[no_mangle]
pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect, mask: *const WrImageMask, filter: WrTextureFilter, key: ImageKey) {
pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect, mask: *const WrImageMask, filter: ImageRendering, key: ImageKey) {
assert!( unsafe { is_in_compositor_thread() });
let bounds = bounds.to_rect();
let clip = clip.to_rect();
//println!("push_image bounds {:?} clip {:?}", bounds, clip);
// convert from the C type to the Rust type, mapping NULL to None
let mask = unsafe { mask.as_ref().map(|m| m.to_image_mask()) };
let image_rendering = filter.to_image_rendering();
let image_rendering = filter;
let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip, Vec::new(), mask);
state.frame_builder.dl_builder.push_image(
@ -700,7 +758,7 @@ pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect
#[no_mangle]
pub extern fn wr_api_add_raw_font(api: &mut RenderApi,
font_buffer: *mut u8,
buffer_size: usize) -> u64
buffer_size: usize) -> FontKey
{
assert!( unsafe { is_in_compositor_thread() });
@ -710,7 +768,7 @@ pub extern fn wr_api_add_raw_font(api: &mut RenderApi,
let mut font_vector = Vec::new();
font_vector.extend_from_slice(font_slice);
return font_key_to_u64(api.add_raw_font(font_vector));
return api.add_raw_font(font_vector);
}
#[no_mangle]
@ -718,15 +776,13 @@ pub extern fn wr_dp_push_text(state: &mut WrState,
bounds: WrRect,
clip: WrRect,
color: WrColor,
font_key: u64,
font_key: FontKey,
glyphs: *mut GlyphInstance,
glyph_count: u32,
glyph_size: f32)
{
assert!( unsafe { is_in_compositor_thread() });
let font_key = u64_to_font_key(font_key);
let glyph_slice = unsafe {
slice::from_raw_parts(glyphs, glyph_count as usize)
};
@ -737,12 +793,14 @@ pub extern fn wr_dp_push_text(state: &mut WrState,
let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
let glyph_options = None; // TODO
state.frame_builder.dl_builder.push_text(bounds.to_rect(),
clip_region,
glyph_vector,
font_key,
colorf,
Au::from_f32_px(glyph_size),
Au::from_px(0));
Au::from_px(0),
glyph_options);
}

Просмотреть файл

@ -10,8 +10,54 @@
#include "mozilla/layers/LayersMessages.h"
#include "mozilla/gfx/Types.h"
// ---
#define WR_DECL_FFI_1(WrType, t1) \
struct WrType { \
t1 mHandle; \
bool operator==(const WrType& rhs) const { \
return mHandle == rhs.mHandle; \
} \
bool operator!=(const WrType& rhs) const { \
return mHandle != rhs.mHandle; \
} \
bool operator<(const WrType& rhs) const { \
return mHandle < rhs.mHandle; \
} \
}; \
// ---
// ---
#define WR_DECL_FFI_2(WrType, t1, t2) \
struct WrType { \
t1 mNamespace; \
t2 mHandle; \
bool operator==(const WrType& rhs) const { \
return mNamespace == rhs.mNamespace \
&& mHandle == rhs.mHandle; \
} \
bool operator!=(const WrType& rhs) const { \
return mNamespace != rhs.mNamespace \
|| mHandle != rhs.mHandle; \
} \
}; \
// ---
extern "C" {
// If you modify any of the declarations below, make sure to update the
// serialization code in WebRenderMessageUtils.h and the rust bindings.
WR_DECL_FFI_1(WrEpoch, uint32_t)
WR_DECL_FFI_1(WrWindowId, uint64_t)
WR_DECL_FFI_2(WrPipelineId, uint32_t, uint32_t)
WR_DECL_FFI_2(WrImageKey, uint32_t, uint32_t)
WR_DECL_FFI_2(WrFontKey, uint32_t, uint32_t)
#undef WR_DECL_FFI_1
#undef WR_DECL_FFI_2
// ----
// Functions invoked from Rust code
// ----
@ -24,37 +70,38 @@ void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
// Enums used in C++ code with corresponding enums in Rust code
// -----
enum class WrImageFormat
enum class WrImageFormat: uint32_t
{
Invalid,
A8,
RGB8,
RGBA8,
RGBAF32,
Invalid = 0,
A8 = 1,
RGB8 = 2,
RGBA8 = 3,
RGBAF32 = 4,
Sentinel /* this must be last, for IPC serialization purposes */
};
enum class WrBorderStyle
enum class WrBorderStyle: uint32_t
{
None,
Solid,
Double,
Dotted,
Dashed,
Hidden,
Groove,
Ridge,
Inset,
Outset,
None = 0,
Solid = 1,
Double = 2,
Dotted = 3,
Dashed = 4,
Hidden = 5,
Groove = 6,
Ridge = 7,
Inset = 8,
Outset = 9,
Sentinel /* this must be last, for IPC serialization purposes */
};
enum class WrTextureFilter
enum class WrImageRendering: uint32_t
{
Linear,
Point,
Auto = 0,
CrispEdges = 1,
Pixelated = 2,
Sentinel /* this must be last, for IPC serialization purposes */
};
@ -66,59 +113,32 @@ enum class WrExternalImageIdType
//// MEM_OR_SHMEM,
};
enum class WrMixBlendMode
enum class WrMixBlendMode: uint32_t
{
Normal,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
HardLight,
SoftLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity,
Normal = 0,
Multiply = 1,
Screen = 2,
Overlay = 3,
Darken = 4,
Lighten = 5,
ColorDodge = 6,
ColorBurn = 7,
HardLight = 8,
SoftLight = 9,
Difference = 10,
Exclusion = 11,
Hue = 12,
Saturation = 13,
Color = 14,
Luminosity = 15,
Sentinel /* this must be last, for IPC serialization purposes */
};
#ifdef DEBUG
// This ensures that the size of |enum class| and |enum| are the same, because
// we use |enum class| in this file (to avoid polluting the global namespace)
// but Rust assumes |enum|. If there is a size mismatch that could lead to
// problems with values being corrupted across the language boundary.
class DebugEnumSizeChecker
{ // scope the enum to the class
enum DummyWrImageFormatEnum
{
Invalid,
A8,
RGB8,
RGBA8,
RGBAF32,
Sentinel
};
static_assert(sizeof(WrImageFormat) == sizeof(DummyWrImageFormatEnum),
"Size of enum doesn't match size of enum class!");
};
#endif
// -----
// Typedefs for struct fields and function signatures below.
// -----
typedef uint64_t WrWindowId;
typedef uint64_t WrImageKey;
typedef uint64_t WrFontKey;
typedef uint64_t WrPipelineId;
typedef uint32_t WrEpoch;
typedef uint64_t WrImageIdType;
// -----
@ -275,6 +295,14 @@ struct WrExternalImageIdHandler
ReleaseExternalImageCallback release_func;
};
struct WrImageDescriptor {
WrImageFormat format;
uint32_t width;
uint32_t height;
uint32_t stride;
bool is_opaque;
};
// -----
// Functions exposed by the webrender API
// -----
@ -338,7 +366,7 @@ WR_INLINE void
wr_gl_init(void* aGLContext)
WR_FUNC;
WR_INLINE void
WR_INLINE bool
wr_window_new(WrWindowId window_id, bool enable_profiler, WrAPI** out_api,
WrRenderer** out_renderer)
WR_FUNC;
@ -348,9 +376,7 @@ wr_api_delete(WrAPI* api)
WR_DESTRUCTOR_SAFE_FUNC;
WR_INLINE WrImageKey
wr_api_add_image(WrAPI* api, uint32_t width, uint32_t height,
uint32_t stride, WrImageFormat format, uint8_t *bytes,
size_t size)
wr_api_add_image(WrAPI* api, const WrImageDescriptor* descriptor, uint8_t *buffer, size_t buffer_size)
WR_FUNC;
WR_INLINE WrImageKey
@ -365,8 +391,9 @@ WR_FUNC;
//// WR_FUNC;
WR_INLINE void
wr_api_update_image(WrAPI* api, WrImageKey key, uint32_t width, uint32_t height,
WrImageFormat format, uint8_t *bytes, size_t size)
wr_api_update_image(WrAPI* api, WrImageKey key,
const WrImageDescriptor* descriptor,
uint8_t *bytes, size_t size)
WR_FUNC;
WR_INLINE void
@ -378,7 +405,7 @@ wr_api_set_root_pipeline(WrAPI* api, WrPipelineId pipeline_id)
WR_FUNC;
WR_INLINE void
wr_api_set_root_display_list(WrAPI* api, WrState* state, uint32_t epoch, float w, float h)
wr_api_set_root_display_list(WrAPI* api, WrState* state, WrEpoch epoch, float w, float h)
WR_FUNC;
WR_INLINE void
@ -409,12 +436,22 @@ WR_INLINE void
wr_dp_pop_stacking_context(WrState *wrState)
WR_FUNC;
WR_INLINE void
wr_dp_push_scroll_layer(WrState *wrState, WrRect bounds,
WrRect overflow, const WrImageMask *mask)
WR_FUNC;
WR_INLINE void
wr_dp_pop_scroll_layer(WrState *wrState)
WR_FUNC;
WR_INLINE void
wr_dp_begin(WrState* wrState, uint32_t width, uint32_t height)
WR_FUNC;
WR_INLINE void
wr_dp_end(WrState* builder, WrAPI* api, uint32_t epoch)
wr_dp_end(WrState* builder, WrAPI* api, WrEpoch epoch)
WR_FUNC;
WR_INLINE void
@ -436,7 +473,7 @@ WR_FUNC;
WR_INLINE void
wr_dp_push_image(WrState* wrState, WrRect bounds, WrRect clip,
const WrImageMask* mask, WrTextureFilter filter, WrImageKey key)
const WrImageMask* mask, WrImageRendering filter, WrImageKey key)
WR_FUNC;
WR_INLINE void

Просмотреть файл

@ -1345,7 +1345,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
if (lm->AsWebRenderLayerManager()) {
TextureFactoryIdentifier textureFactoryIdentifier;
lm->AsWebRenderLayerManager()->Initialize(mCompositorBridgeChild,
mCompositorSession->RootLayerTreeId(),
wr::AsPipelineId(mCompositorSession->RootLayerTreeId()),
&textureFactoryIdentifier);
ImageBridgeChild::IdentifyCompositorTextureHost(textureFactoryIdentifier);
gfx::VRManagerChild::IdentifyTextureHost(textureFactoryIdentifier);