mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-14 11:21:40 +00:00
Add dawn_wire entrypoints to inject texture in the wire
This allows reserving a texture ID in the client and injecting textures in the wire, so that the WebGPU control channel can create WebGPU textures backed by SharedImages in Chromium. BUG=941543 Change-Id: I1efcfe3dce024bb2d3592f22225407a97b641c1f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/5820 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
e821ed6781
commit
339bd9d447
1
BUILD.gn
1
BUILD.gn
@ -593,6 +593,7 @@ test("dawn_unittests") {
|
|||||||
"src/tests/unittests/wire/WireBufferMappingTests.cpp",
|
"src/tests/unittests/wire/WireBufferMappingTests.cpp",
|
||||||
"src/tests/unittests/wire/WireCallbackTests.cpp",
|
"src/tests/unittests/wire/WireCallbackTests.cpp",
|
||||||
"src/tests/unittests/wire/WireFenceTests.cpp",
|
"src/tests/unittests/wire/WireFenceTests.cpp",
|
||||||
|
"src/tests/unittests/wire/WireInjectTextureTests.cpp",
|
||||||
"src/tests/unittests/wire/WireOptionalTests.cpp",
|
"src/tests/unittests/wire/WireOptionalTests.cpp",
|
||||||
"src/tests/unittests/wire/WireTest.cpp",
|
"src/tests/unittests/wire/WireTest.cpp",
|
||||||
"src/tests/unittests/wire/WireTest.h",
|
"src/tests/unittests/wire/WireTest.h",
|
||||||
|
@ -36,4 +36,8 @@ namespace dawn_wire {
|
|||||||
return mImpl->HandleCommands(commands, size);
|
return mImpl->HandleCommands(commands, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReservedTexture WireClient::ReserveTexture(DawnDevice device) {
|
||||||
|
return mImpl->ReserveTexture(device);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dawn_wire
|
} // namespace dawn_wire
|
||||||
|
@ -31,4 +31,8 @@ namespace dawn_wire {
|
|||||||
return mImpl->HandleCommands(commands, size);
|
return mImpl->HandleCommands(commands, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WireServer::InjectTexture(DawnTexture texture, uint32_t id, uint32_t generation) {
|
||||||
|
return mImpl->InjectTexture(texture, id, generation);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dawn_wire
|
} // namespace dawn_wire
|
||||||
|
@ -27,4 +27,15 @@ namespace dawn_wire { namespace client {
|
|||||||
DeviceAllocator().Free(mDevice);
|
DeviceAllocator().Free(mDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReservedTexture Client::ReserveTexture(DawnDevice cDevice) {
|
||||||
|
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||||
|
ObjectAllocator<Texture>::ObjectAndSerial* allocation = TextureAllocator().New(device);
|
||||||
|
|
||||||
|
ReservedTexture result;
|
||||||
|
result.texture = reinterpret_cast<DawnTexture>(allocation->object.get());
|
||||||
|
result.id = allocation->object->id;
|
||||||
|
result.generation = allocation->serial;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace dawn_wire::client
|
}} // namespace dawn_wire::client
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <dawn_wire/Wire.h>
|
#include <dawn_wire/Wire.h>
|
||||||
|
|
||||||
|
#include "dawn_wire/WireClient.h"
|
||||||
#include "dawn_wire/WireCmd_autogen.h"
|
#include "dawn_wire/WireCmd_autogen.h"
|
||||||
#include "dawn_wire/WireDeserializeAllocator.h"
|
#include "dawn_wire/WireDeserializeAllocator.h"
|
||||||
#include "dawn_wire/client/ClientBase_autogen.h"
|
#include "dawn_wire/client/ClientBase_autogen.h"
|
||||||
@ -31,6 +32,7 @@ namespace dawn_wire { namespace client {
|
|||||||
~Client();
|
~Client();
|
||||||
|
|
||||||
const char* HandleCommands(const char* commands, size_t size);
|
const char* HandleCommands(const char* commands, size_t size);
|
||||||
|
ReservedTexture ReserveTexture(DawnDevice device);
|
||||||
|
|
||||||
void* GetCmdSpace(size_t size) {
|
void* GetCmdSpace(size_t size) {
|
||||||
return mSerializer->GetCmdSpace(size);
|
return mSerializer->GetCmdSpace(size);
|
||||||
|
@ -24,7 +24,7 @@ namespace dawn_wire { namespace server {
|
|||||||
deviceData->valid = true;
|
deviceData->valid = true;
|
||||||
|
|
||||||
auto userdata = static_cast<DawnCallbackUserdata>(reinterpret_cast<intptr_t>(this));
|
auto userdata = static_cast<DawnCallbackUserdata>(reinterpret_cast<intptr_t>(this));
|
||||||
procs.deviceSetErrorCallback(device, ForwardDeviceError, userdata);
|
mProcs.deviceSetErrorCallback(device, ForwardDeviceError, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server() {
|
Server::~Server() {
|
||||||
@ -35,4 +35,22 @@ namespace dawn_wire { namespace server {
|
|||||||
return mSerializer->GetCmdSpace(size);
|
return mSerializer->GetCmdSpace(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::InjectTexture(DawnTexture texture, uint32_t id, uint32_t generation) {
|
||||||
|
ObjectData<DawnTexture>* data = TextureObjects().Allocate(id);
|
||||||
|
if (data == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->handle = texture;
|
||||||
|
data->serial = generation;
|
||||||
|
data->valid = true;
|
||||||
|
data->allocated = true;
|
||||||
|
|
||||||
|
// The texture is externally owned so it shouldn't be destroyed when we receive a destroy
|
||||||
|
// message from the client. Add a reference to counterbalance the eventual release.
|
||||||
|
mProcs.textureReference(texture);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace dawn_wire::server
|
}} // namespace dawn_wire::server
|
||||||
|
@ -42,6 +42,8 @@ namespace dawn_wire { namespace server {
|
|||||||
|
|
||||||
const char* HandleCommands(const char* commands, size_t size);
|
const char* HandleCommands(const char* commands, size_t size);
|
||||||
|
|
||||||
|
bool InjectTexture(DawnTexture texture, uint32_t id, uint32_t generation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* GetCmdSpace(size_t size);
|
void* GetCmdSpace(size_t size);
|
||||||
|
|
||||||
|
@ -25,6 +25,12 @@ namespace dawn_wire {
|
|||||||
class Client;
|
class Client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ReservedTexture {
|
||||||
|
DawnTexture texture;
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t generation;
|
||||||
|
};
|
||||||
|
|
||||||
class DAWN_WIRE_EXPORT WireClient : public CommandHandler {
|
class DAWN_WIRE_EXPORT WireClient : public CommandHandler {
|
||||||
public:
|
public:
|
||||||
WireClient(CommandSerializer* serializer);
|
WireClient(CommandSerializer* serializer);
|
||||||
@ -34,6 +40,8 @@ namespace dawn_wire {
|
|||||||
DawnProcTable GetProcs() const;
|
DawnProcTable GetProcs() const;
|
||||||
const char* HandleCommands(const char* commands, size_t size) override final;
|
const char* HandleCommands(const char* commands, size_t size) override final;
|
||||||
|
|
||||||
|
ReservedTexture ReserveTexture(DawnDevice device);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<client::Client> mImpl;
|
std::unique_ptr<client::Client> mImpl;
|
||||||
};
|
};
|
||||||
|
@ -32,6 +32,8 @@ namespace dawn_wire {
|
|||||||
|
|
||||||
const char* HandleCommands(const char* commands, size_t size) override final;
|
const char* HandleCommands(const char* commands, size_t size) override final;
|
||||||
|
|
||||||
|
bool InjectTexture(DawnTexture texture, uint32_t id, uint32_t generation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<server::Server> mImpl;
|
std::unique_ptr<server::Server> mImpl;
|
||||||
};
|
};
|
||||||
|
83
src/tests/unittests/wire/WireInjectTextureTests.cpp
Normal file
83
src/tests/unittests/wire/WireInjectTextureTests.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// Copyright 2019 The Dawn Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "tests/unittests/wire/WireTest.h"
|
||||||
|
|
||||||
|
#include "dawn_wire/WireClient.h"
|
||||||
|
#include "dawn_wire/WireServer.h"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace dawn_wire;
|
||||||
|
|
||||||
|
class WireInjectTextureTests : public WireTest {
|
||||||
|
public:
|
||||||
|
WireInjectTextureTests() : WireTest(true) {
|
||||||
|
}
|
||||||
|
~WireInjectTextureTests() override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test that reserving and injecting a texture makes calls on the client object forward to the
|
||||||
|
// server object correctly.
|
||||||
|
TEST_F(WireInjectTextureTests, CallAfterReserveInject) {
|
||||||
|
ReservedTexture reservation = GetWireClient()->ReserveTexture(device);
|
||||||
|
|
||||||
|
DawnTexture apiTexture = api.GetNewTexture();
|
||||||
|
EXPECT_CALL(api, TextureReference(apiTexture));
|
||||||
|
ASSERT_TRUE(GetWireServer()->InjectTexture(apiTexture, reservation.id, reservation.generation));
|
||||||
|
|
||||||
|
dawnTextureCreateDefaultTextureView(reservation.texture);
|
||||||
|
EXPECT_CALL(api, TextureCreateDefaultTextureView(apiTexture)).WillOnce(Return(nullptr));
|
||||||
|
FlushClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that reserve correctly returns different IDs each time.
|
||||||
|
TEST_F(WireInjectTextureTests, ReserveDifferentIDs) {
|
||||||
|
ReservedTexture reservation1 = GetWireClient()->ReserveTexture(device);
|
||||||
|
ReservedTexture reservation2 = GetWireClient()->ReserveTexture(device);
|
||||||
|
|
||||||
|
ASSERT_NE(reservation1.id, reservation2.id);
|
||||||
|
ASSERT_NE(reservation1.texture, reservation2.texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that injecting the same id without a destroy first fails.
|
||||||
|
TEST_F(WireInjectTextureTests, InjectExistingID) {
|
||||||
|
ReservedTexture reservation = GetWireClient()->ReserveTexture(device);
|
||||||
|
|
||||||
|
DawnTexture apiTexture = api.GetNewTexture();
|
||||||
|
EXPECT_CALL(api, TextureReference(apiTexture));
|
||||||
|
ASSERT_TRUE(GetWireServer()->InjectTexture(apiTexture, reservation.id, reservation.generation));
|
||||||
|
|
||||||
|
// ID already in use, call fails.
|
||||||
|
ASSERT_FALSE(
|
||||||
|
GetWireServer()->InjectTexture(apiTexture, reservation.id, reservation.generation));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the server only borrows the texture and does a single reference-release
|
||||||
|
TEST_F(WireInjectTextureTests, InjectedTextureLifetime) {
|
||||||
|
ReservedTexture reservation = GetWireClient()->ReserveTexture(device);
|
||||||
|
|
||||||
|
// Injecting the texture adds a reference
|
||||||
|
DawnTexture apiTexture = api.GetNewTexture();
|
||||||
|
EXPECT_CALL(api, TextureReference(apiTexture));
|
||||||
|
ASSERT_TRUE(GetWireServer()->InjectTexture(apiTexture, reservation.id, reservation.generation));
|
||||||
|
|
||||||
|
// Releasing the texture removes a single reference.
|
||||||
|
dawnTextureRelease(reservation.texture);
|
||||||
|
EXPECT_CALL(api, TextureRelease(apiTexture));
|
||||||
|
FlushClient();
|
||||||
|
|
||||||
|
// Deleting the server doesn't release a second reference.
|
||||||
|
DeleteServer();
|
||||||
|
Mock::VerifyAndClearExpectations(&api);
|
||||||
|
}
|
@ -74,6 +74,18 @@ void WireTest::FlushServer() {
|
|||||||
ASSERT_TRUE(mS2cBuf->Flush());
|
ASSERT_TRUE(mS2cBuf->Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dawn_wire::WireServer* WireTest::GetWireServer() {
|
||||||
|
return mWireServer.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn_wire::WireClient* WireTest::GetWireClient() {
|
||||||
|
return mWireClient.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireTest::DeleteServer() {
|
||||||
|
mWireServer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void WireTest::SetupIgnoredCallExpectations() {
|
void WireTest::SetupIgnoredCallExpectations() {
|
||||||
if (mIgnoreSetCallbackCalls) {
|
if (mIgnoreSetCallbackCalls) {
|
||||||
EXPECT_CALL(api, OnBuilderSetErrorCallback(_, _, _, _)).Times(AnyNumber());
|
EXPECT_CALL(api, OnBuilderSetErrorCallback(_, _, _, _)).Times(AnyNumber());
|
||||||
|
@ -89,6 +89,11 @@ class WireTest : public testing::Test {
|
|||||||
DawnDevice apiDevice;
|
DawnDevice apiDevice;
|
||||||
DawnDevice device;
|
DawnDevice device;
|
||||||
|
|
||||||
|
dawn_wire::WireServer* GetWireServer();
|
||||||
|
dawn_wire::WireClient* GetWireClient();
|
||||||
|
|
||||||
|
void DeleteServer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupIgnoredCallExpectations();
|
void SetupIgnoredCallExpectations();
|
||||||
bool mIgnoreSetCallbackCalls = false;
|
bool mIgnoreSetCallbackCalls = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user