Factor wire server handlers into proper command handlers and doers
Bug: dawn:88 Change-Id: If637e7ac694d68ad7a4a1e85fd241e8b48e62f6a Reviewed-on: https://dawn-review.googlesource.com/c/4060 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
3b71e65658
commit
62e83971ca
1
BUILD.gn
1
BUILD.gn
|
@ -779,6 +779,7 @@ dawn_generator("libdawn_wire_gen") {
|
||||||
"dawn_wire/client/ClientPrototypes_autogen.inl",
|
"dawn_wire/client/ClientPrototypes_autogen.inl",
|
||||||
"dawn_wire/server/ServerBase_autogen.h",
|
"dawn_wire/server/ServerBase_autogen.h",
|
||||||
"dawn_wire/server/ServerCallbacks_autogen.cpp",
|
"dawn_wire/server/ServerCallbacks_autogen.cpp",
|
||||||
|
"dawn_wire/server/ServerDoers_autogen.cpp",
|
||||||
"dawn_wire/server/ServerHandlers_autogen.cpp",
|
"dawn_wire/server/ServerHandlers_autogen.cpp",
|
||||||
"dawn_wire/server/ServerPrototypes_autogen.inl",
|
"dawn_wire/server/ServerPrototypes_autogen.inl",
|
||||||
]
|
]
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
"server_custom_pre_handler_commands": [
|
"server_custom_pre_handler_commands": [
|
||||||
"BufferUnmap"
|
"BufferUnmap"
|
||||||
],
|
],
|
||||||
"server_custom_post_handler_commands": [
|
"server_handwritten_commands": [
|
||||||
"QueueSignal"
|
"QueueSignal"
|
||||||
],
|
],
|
||||||
"server_reverse_lookup_objects": [
|
"server_reverse_lookup_objects": [
|
||||||
|
|
|
@ -311,12 +311,17 @@ def js_native_methods(types, typ):
|
||||||
def debug(text):
|
def debug(text):
|
||||||
print(text)
|
print(text)
|
||||||
|
|
||||||
|
def do_assert(expr):
|
||||||
|
assert expr
|
||||||
|
return ''
|
||||||
|
|
||||||
def get_renders_for_targets(api_params, wire_json, targets):
|
def get_renders_for_targets(api_params, wire_json, targets):
|
||||||
base_params = {
|
base_params = {
|
||||||
'enumerate': enumerate,
|
'enumerate': enumerate,
|
||||||
'format': format,
|
'format': format,
|
||||||
'len': len,
|
'len': len,
|
||||||
'debug': debug,
|
'debug': debug,
|
||||||
|
'assert': do_assert,
|
||||||
|
|
||||||
'Name': lambda name: Name(name),
|
'Name': lambda name: Name(name),
|
||||||
|
|
||||||
|
@ -393,6 +398,7 @@ def get_renders_for_targets(api_params, wire_json, targets):
|
||||||
renders.append(FileRender('dawn_wire/client/ClientPrototypes.inl', 'dawn_wire/client/ClientPrototypes_autogen.inl', wire_params))
|
renders.append(FileRender('dawn_wire/client/ClientPrototypes.inl', 'dawn_wire/client/ClientPrototypes_autogen.inl', wire_params))
|
||||||
renders.append(FileRender('dawn_wire/server/ServerBase.h', 'dawn_wire/server/ServerBase_autogen.h', wire_params))
|
renders.append(FileRender('dawn_wire/server/ServerBase.h', 'dawn_wire/server/ServerBase_autogen.h', wire_params))
|
||||||
renders.append(FileRender('dawn_wire/server/ServerCallbacks.cpp', 'dawn_wire/server/ServerCallbacks_autogen.cpp', wire_params))
|
renders.append(FileRender('dawn_wire/server/ServerCallbacks.cpp', 'dawn_wire/server/ServerCallbacks_autogen.cpp', wire_params))
|
||||||
|
renders.append(FileRender('dawn_wire/server/ServerDoers.cpp', 'dawn_wire/server/ServerDoers_autogen.cpp', wire_params))
|
||||||
renders.append(FileRender('dawn_wire/server/ServerHandlers.cpp', 'dawn_wire/server/ServerHandlers_autogen.cpp', wire_params))
|
renders.append(FileRender('dawn_wire/server/ServerHandlers.cpp', 'dawn_wire/server/ServerHandlers_autogen.cpp', wire_params))
|
||||||
renders.append(FileRender('dawn_wire/server/ServerPrototypes.inl', 'dawn_wire/server/ServerPrototypes_autogen.inl', wire_params))
|
renders.append(FileRender('dawn_wire/server/ServerPrototypes.inl', 'dawn_wire/server/ServerPrototypes_autogen.inl', wire_params))
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
namespace dawn_wire { namespace server {
|
namespace dawn_wire { namespace server {
|
||||||
{% for type in by_category["object"] if type.is_builder%}
|
{% for type in by_category["object"] if type.is_builder%}
|
||||||
void Server::Forward{{type.name.CamelCase()}}ToClient(dawnBuilderErrorStatus status, const char* message, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2) {
|
void Server::Forward{{type.name.CamelCase()}}(dawnBuilderErrorStatus status, const char* message, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2) {
|
||||||
auto server = reinterpret_cast<Server*>(static_cast<uintptr_t>(userdata1));
|
auto server = reinterpret_cast<Server*>(static_cast<uintptr_t>(userdata1));
|
||||||
uint32_t id = userdata2 & 0xFFFFFFFFu;
|
uint32_t id = userdata2 & 0xFFFFFFFFu;
|
||||||
uint32_t serial = userdata2 >> uint64_t(32);
|
uint32_t serial = userdata2 >> uint64_t(32);
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
//* 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 "common/Assert.h"
|
||||||
|
#include "dawn_wire/server/Server.h"
|
||||||
|
|
||||||
|
namespace dawn_wire { namespace server {
|
||||||
|
//* Implementation of the command doers
|
||||||
|
{% for command in cmd_records["command"] %}
|
||||||
|
{% set type = command.derived_object %}
|
||||||
|
{% set method = command.derived_method %}
|
||||||
|
{% set is_method = method is not none %}
|
||||||
|
|
||||||
|
{% set Suffix = command.name.CamelCase() %}
|
||||||
|
{% if Suffix not in client_side_commands %}
|
||||||
|
{% if is_method and Suffix not in server_handwritten_commands %}
|
||||||
|
bool Server::Do{{Suffix}}(
|
||||||
|
{%- for member in command.members -%}
|
||||||
|
{%- if member.is_return_value -%}
|
||||||
|
{%- if member.handle_type -%}
|
||||||
|
{{as_cType(member.handle_type.name)}}* {{as_varName(member.name)}}
|
||||||
|
{%- else -%}
|
||||||
|
{{as_cType(member.type.name)}}* {{as_varName(member.name)}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- else -%}
|
||||||
|
{{as_annotated_cType(member)}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if not loop.last -%}, {% endif %}
|
||||||
|
{%- endfor -%}
|
||||||
|
) {
|
||||||
|
{% set ret = command.members|selectattr("is_return_value")|list %}
|
||||||
|
//* If there is a return value, assign it.
|
||||||
|
{% if ret|length == 1 %}
|
||||||
|
*{{as_varName(ret[0].name)}} =
|
||||||
|
{% else %}
|
||||||
|
//* Only one member should be a return value.
|
||||||
|
{{ assert(ret|length == 0) }}
|
||||||
|
{% endif %}
|
||||||
|
mProcs.{{as_varName(type.name, method.name)}}(
|
||||||
|
{%- for member in command.members if not member.is_return_value -%}
|
||||||
|
{{as_varName(member.name)}}
|
||||||
|
{%- if not loop.last -%}, {% endif %}
|
||||||
|
{%- endfor -%}
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
bool Server::DoDestroyObject(ObjectType objectType, ObjectId objectId) {
|
||||||
|
//* ID 0 are reserved for nullptr and cannot be destroyed.
|
||||||
|
if (objectId == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(objectType) {
|
||||||
|
{% for type in by_category["object"] %}
|
||||||
|
case ObjectType::{{type.name.CamelCase()}}: {
|
||||||
|
{% if type.name.CamelCase() == "Device" %}
|
||||||
|
//* Freeing the device has to be done out of band.
|
||||||
|
return false;
|
||||||
|
{% else %}
|
||||||
|
auto* data = {{type.name.CamelCase()}}Objects().Get(objectId);
|
||||||
|
if (data == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
{% if type.name.CamelCase() in server_reverse_lookup_objects %}
|
||||||
|
{{type.name.CamelCase()}}ObjectIdTable().Remove(data->handle);
|
||||||
|
{% endif %}
|
||||||
|
if (data->handle != nullptr) {
|
||||||
|
mProcs.{{as_varName(type.name, Name("release"))}}(data->handle);
|
||||||
|
}
|
||||||
|
{{type.name.CamelCase()}}Objects().Free(objectId);
|
||||||
|
return true;
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace dawn_wire::server
|
|
@ -16,144 +16,120 @@
|
||||||
#include "dawn_wire/server/Server.h"
|
#include "dawn_wire/server/Server.h"
|
||||||
|
|
||||||
namespace dawn_wire { namespace server {
|
namespace dawn_wire { namespace server {
|
||||||
{% for type in by_category["object"] %}
|
{% for command in cmd_records["command"] %}
|
||||||
{% for method in type.methods %}
|
{% set type = command.derived_object %}
|
||||||
{% set Suffix = as_MethodSuffix(type.name, method.name) %}
|
{% set method = command.derived_method %}
|
||||||
{% if Suffix not in client_side_commands %}
|
{% set is_method = method != None %}
|
||||||
//* The generic command handlers
|
{% set returns = is_method and method.return_type.name.canonical_case() != "void" %}
|
||||||
|
|
||||||
bool Server::Handle{{Suffix}}(const char** commands, size_t* size) {
|
{% set Suffix = command.name.CamelCase() %}
|
||||||
{{Suffix}}Cmd cmd;
|
{% if Suffix not in client_side_commands %}
|
||||||
DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator, *this);
|
//* The generic command handlers
|
||||||
|
bool Server::Handle{{Suffix}}(const char** commands, size_t* size) {
|
||||||
|
{{Suffix}}Cmd cmd;
|
||||||
|
DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator
|
||||||
|
{%- if command.has_dawn_object -%}
|
||||||
|
, *this
|
||||||
|
{%- endif -%}
|
||||||
|
);
|
||||||
|
|
||||||
if (deserializeResult == DeserializeResult::FatalError) {
|
if (deserializeResult == DeserializeResult::FatalError) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if Suffix in server_custom_pre_handler_commands %}
|
||||||
|
if (!PreHandle{{Suffix}}(cmd)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if Suffix in server_custom_pre_handler_commands %}
|
{% if is_method %}
|
||||||
if (!PreHandle{{Suffix}}(cmd)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
//* Unpack 'self'
|
//* Unpack 'self'
|
||||||
auto* selfData = {{type.name.CamelCase()}}Objects().Get(cmd.selfId);
|
auto* selfData = {{type.name.CamelCase()}}Objects().Get(cmd.selfId);
|
||||||
ASSERT(selfData != nullptr);
|
ASSERT(selfData != nullptr);
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
//* In all cases allocate the object data as it will be refered-to by the client.
|
//* Allocate any result objects
|
||||||
{% set return_type = method.return_type %}
|
{%- for member in command.members if member.is_return_value -%}
|
||||||
{% set returns = return_type.name.canonical_case() != "void" %}
|
{{ assert(member.handle_type) }}
|
||||||
{% if returns %}
|
{% set Type = member.handle_type.name.CamelCase() %}
|
||||||
{% set Type = method.return_type.name.CamelCase() %}
|
{% set name = as_varName(member.name) %}
|
||||||
auto* resultData = {{Type}}Objects().Allocate(cmd.result.id);
|
|
||||||
if (resultData == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
resultData->serial = cmd.result.serial;
|
|
||||||
|
|
||||||
{% if type.is_builder %}
|
auto* {{name}}Data = {{Type}}Objects().Allocate(cmd.{{name}}.id);
|
||||||
selfData->builtObject = cmd.result;
|
if ({{name}}Data == nullptr) {
|
||||||
{% endif %}
|
return false;
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
//* After the data is allocated, apply the argument error propagation mechanism
|
|
||||||
if (deserializeResult == DeserializeResult::ErrorObject) {
|
|
||||||
{% if type.is_builder %}
|
|
||||||
selfData->valid = false;
|
|
||||||
//* If we are in GetResult, fake an error callback
|
|
||||||
{% if returns %}
|
|
||||||
On{{type.name.CamelCase()}}Error(DAWN_BUILDER_ERROR_STATUS_ERROR, "Maybe monad", cmd.selfId, selfData->serial);
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
{{name}}Data->serial = cmd.{{name}}.serial;
|
||||||
|
|
||||||
{% if returns %}
|
{% if type.is_builder %}
|
||||||
auto result ={{" "}}
|
selfData->builtObject = cmd.{{name}};
|
||||||
{%- endif %}
|
|
||||||
mProcs.{{as_varName(type.name, method.name)}}(cmd.self
|
|
||||||
{%- for arg in method.arguments -%}
|
|
||||||
, cmd.{{as_varName(arg.name)}}
|
|
||||||
{%- endfor -%}
|
|
||||||
);
|
|
||||||
|
|
||||||
{% if Suffix in server_custom_post_handler_commands %}
|
|
||||||
if (!PostHandle{{Suffix}}(cmd)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% if returns %}
|
//* After the data is allocated, apply the argument error propagation mechanism
|
||||||
resultData->handle = result;
|
if (deserializeResult == DeserializeResult::ErrorObject) {
|
||||||
resultData->valid = result != nullptr;
|
{% if type.is_builder %}
|
||||||
|
selfData->valid = false;
|
||||||
{% if return_type.name.CamelCase() in server_reverse_lookup_objects %}
|
//* If we are in GetResult, fake an error callback
|
||||||
//* For created objects, store a mapping from them back to their client IDs
|
{% if returns %}
|
||||||
if (result) {
|
On{{type.name.CamelCase()}}Error(DAWN_BUILDER_ERROR_STATUS_ERROR, "Maybe monad", cmd.selfId, selfData->serial);
|
||||||
{{return_type.name.CamelCase()}}ObjectIdTable().Store(result, cmd.result.id);
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
//* builders remember the ID of the object they built so that they can send it
|
|
||||||
//* in the callback to the client.
|
|
||||||
{% if return_type.is_builder %}
|
|
||||||
if (result != nullptr) {
|
|
||||||
uint64_t userdata1 = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this));
|
|
||||||
uint64_t userdata2 = (uint64_t(resultData->serial) << uint64_t(32)) + cmd.result.id;
|
|
||||||
mProcs.{{as_varName(return_type.name, Name("set error callback"))}}(result, Forward{{return_type.name.CamelCase()}}ToClient, userdata1, userdata2);
|
|
||||||
}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
bool Server::HandleDestroyObject(const char** commands, size_t* size) {
|
//* Do command
|
||||||
DestroyObjectCmd cmd;
|
bool success = Do{{Suffix}}(
|
||||||
DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
|
{%- for member in command.members -%}
|
||||||
|
{%- if member.is_return_value -%}
|
||||||
|
{%- if member.handle_type -%}
|
||||||
|
&{{as_varName(member.name)}}Data->handle //* Pass the handle of the output object to be written by the doer
|
||||||
|
{%- else -%}
|
||||||
|
&cmd.{{as_varName(member.name)}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- else -%}
|
||||||
|
cmd.{{as_varName(member.name)}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if not loop.last -%}, {% endif %}
|
||||||
|
{%- endfor -%}
|
||||||
|
);
|
||||||
|
|
||||||
if (deserializeResult == DeserializeResult::FatalError) {
|
//* Mark output object handles as valid/invalid
|
||||||
return false;
|
{%- for member in command.members if member.is_return_value and member.handle_type -%}
|
||||||
}
|
{% set name = as_varName(member.name) %}
|
||||||
|
{{name}}Data->valid = {{name}}Data->handle != nullptr;
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
ObjectId objectId = cmd.objectId;
|
if (!success) {
|
||||||
//* ID 0 are reserved for nullptr and cannot be destroyed.
|
return false;
|
||||||
if (objectId == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cmd.objectType) {
|
|
||||||
{% for type in by_category["object"] %}
|
|
||||||
{% set ObjectType = type.name.CamelCase() %}
|
|
||||||
case ObjectType::{{ObjectType}}: {
|
|
||||||
{% if ObjectType == "Device" %}
|
|
||||||
//* Freeing the device has to be done out of band.
|
|
||||||
return false;
|
|
||||||
{% else %}
|
|
||||||
auto* data = {{type.name.CamelCase()}}Objects().Get(objectId);
|
|
||||||
if (data == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
{% if type.name.CamelCase() in server_reverse_lookup_objects %}
|
|
||||||
{{type.name.CamelCase()}}ObjectIdTable().Remove(data->handle);
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
if (data->handle != nullptr) {
|
|
||||||
mProcs.{{as_varName(type.name, Name("release"))}}(data->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
{{type.name.CamelCase()}}Objects().Free(objectId);
|
|
||||||
return true;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
{% endfor %}
|
|
||||||
default:
|
{%- for member in command.members if member.is_return_value and member.handle_type -%}
|
||||||
UNREACHABLE();
|
{% set Type = member.handle_type.name.CamelCase() %}
|
||||||
}
|
{% set name = as_varName(member.name) %}
|
||||||
}
|
|
||||||
|
{% if Type in server_reverse_lookup_objects %}
|
||||||
|
//* For created objects, store a mapping from them back to their client IDs
|
||||||
|
if ({{name}}Data->valid) {
|
||||||
|
{{Type}}ObjectIdTable().Store({{name}}Data->handle, cmd.{{name}}.id);
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
//* builders remember the ID of the object they built so that they can send it
|
||||||
|
//* in the callback to the client.
|
||||||
|
{% if member.handle_type.is_builder %}
|
||||||
|
if ({{name}}Data->valid) {
|
||||||
|
uint64_t userdata1 = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this));
|
||||||
|
uint64_t userdata2 = (uint64_t({{name}}Data->serial) << uint64_t(32)) + cmd.{{name}}.id;
|
||||||
|
mProcs.{{as_varName(member.handle_type.name, Name("set error callback"))}}({{name}}Data->handle, Forward{{Type}}, userdata1, userdata2);
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
const char* Server::HandleCommands(const char* commands, size_t size) {
|
const char* Server::HandleCommands(const char* commands, size_t size) {
|
||||||
mProcs.deviceTick(DeviceObjects().Get(1)->handle);
|
mProcs.deviceTick(DeviceObjects().Get(1)->handle);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
// Forwarding callbacks
|
// Forwarding callbacks
|
||||||
{% for type in by_category["object"] if type.is_builder%}
|
{% for type in by_category["object"] if type.is_builder%}
|
||||||
static void Forward{{type.name.CamelCase()}}ToClient(dawnBuilderErrorStatus status, const char* message, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2);
|
static void Forward{{type.name.CamelCase()}}(dawnBuilderErrorStatus status, const char* message, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2);
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
// Error callbacks
|
// Error callbacks
|
||||||
|
@ -23,12 +23,27 @@
|
||||||
void On{{Type}}Error(dawnBuilderErrorStatus status, const char* message, uint32_t id, uint32_t serial);
|
void On{{Type}}Error(dawnBuilderErrorStatus status, const char* message, uint32_t id, uint32_t serial);
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers & doers
|
||||||
{% for type in by_category["object"] %}
|
{% for command in cmd_records["command"] if command.name.CamelCase() not in client_side_commands %}
|
||||||
{% for method in type.methods %}
|
{% set Suffix = command.name.CamelCase() %}
|
||||||
{% set Suffix = as_MethodSuffix(type.name, method.name) %}
|
bool Handle{{Suffix}}(const char** commands, size_t* size);
|
||||||
{% if Suffix not in client_side_commands %}
|
|
||||||
bool Handle{{Suffix}}(const char** commands, size_t* size);
|
bool Do{{Suffix}}(
|
||||||
{% endif %}
|
{%- for member in command.members -%}
|
||||||
{% endfor %}
|
{%- if member.is_return_value -%}
|
||||||
|
{%- if member.handle_type -%}
|
||||||
|
{{as_cType(member.handle_type.name)}}* {{as_varName(member.name)}}
|
||||||
|
{%- else -%}
|
||||||
|
{{as_cType(member.type.name)}}* {{as_varName(member.name)}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- else -%}
|
||||||
|
{{as_annotated_cType(member)}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if not loop.last -%}, {% endif %}
|
||||||
|
{%- endfor -%}
|
||||||
|
);
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for CommandName in server_custom_pre_handler_commands %}
|
||||||
|
bool PreHandle{{CommandName}}(const {{CommandName}}Cmd& cmd);
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -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, ForwardDeviceErrorToServer, userdata);
|
procs.deviceSetErrorCallback(device, ForwardDeviceError, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server() {
|
Server::~Server() {
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace dawn_wire { namespace server {
|
||||||
void* GetCmdSpace(size_t size);
|
void* GetCmdSpace(size_t size);
|
||||||
|
|
||||||
// Forwarding callbacks
|
// Forwarding callbacks
|
||||||
static void ForwardDeviceErrorToServer(const char* message, dawnCallbackUserdata userdata);
|
static void ForwardDeviceError(const char* message, dawnCallbackUserdata userdata);
|
||||||
static void ForwardBufferMapReadAsync(dawnBufferMapAsyncStatus status,
|
static void ForwardBufferMapReadAsync(dawnBufferMapAsyncStatus status,
|
||||||
const void* ptr,
|
const void* ptr,
|
||||||
dawnCallbackUserdata userdata);
|
dawnCallbackUserdata userdata);
|
||||||
|
@ -66,13 +66,6 @@ namespace dawn_wire { namespace server {
|
||||||
MapUserdata* userdata);
|
MapUserdata* userdata);
|
||||||
void OnFenceCompletedValueUpdated(FenceCompletionUserdata* userdata);
|
void OnFenceCompletedValueUpdated(FenceCompletionUserdata* userdata);
|
||||||
|
|
||||||
// Command handlers
|
|
||||||
bool PreHandleBufferUnmap(const BufferUnmapCmd& cmd);
|
|
||||||
bool PostHandleQueueSignal(const QueueSignalCmd& cmd);
|
|
||||||
bool HandleBufferMapAsync(const char** commands, size_t* size);
|
|
||||||
bool HandleBufferUpdateMappedData(const char** commands, size_t* size);
|
|
||||||
bool HandleDestroyObject(const char** commands, size_t* size);
|
|
||||||
|
|
||||||
#include "dawn_wire/server/ServerPrototypes_autogen.inl"
|
#include "dawn_wire/server/ServerPrototypes_autogen.inl"
|
||||||
|
|
||||||
CommandSerializer* mSerializer = nullptr;
|
CommandSerializer* mSerializer = nullptr;
|
||||||
|
|
|
@ -21,28 +21,20 @@ namespace dawn_wire { namespace server {
|
||||||
|
|
||||||
bool Server::PreHandleBufferUnmap(const BufferUnmapCmd& cmd) {
|
bool Server::PreHandleBufferUnmap(const BufferUnmapCmd& cmd) {
|
||||||
auto* selfData = BufferObjects().Get(cmd.selfId);
|
auto* selfData = BufferObjects().Get(cmd.selfId);
|
||||||
ASSERT(selfData != nullptr);
|
DAWN_ASSERT(selfData != nullptr);
|
||||||
|
|
||||||
selfData->mappedData = nullptr;
|
selfData->mappedData = nullptr;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::HandleBufferMapAsync(const char** commands, size_t* size) {
|
bool Server::DoBufferMapAsync(ObjectId bufferId,
|
||||||
|
uint32_t requestSerial,
|
||||||
|
uint32_t start,
|
||||||
|
uint32_t size,
|
||||||
|
bool isWrite) {
|
||||||
// These requests are just forwarded to the buffer, with userdata containing what the
|
// These requests are just forwarded to the buffer, with userdata containing what the
|
||||||
// client will require in the return command.
|
// client will require in the return command.
|
||||||
BufferMapAsyncCmd cmd;
|
|
||||||
DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
|
|
||||||
|
|
||||||
if (deserializeResult == DeserializeResult::FatalError) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectId bufferId = cmd.bufferId;
|
|
||||||
uint32_t requestSerial = cmd.requestSerial;
|
|
||||||
uint32_t requestSize = cmd.size;
|
|
||||||
uint32_t requestStart = cmd.start;
|
|
||||||
bool isWrite = cmd.isWrite;
|
|
||||||
|
|
||||||
// The null object isn't valid as `self`
|
// The null object isn't valid as `self`
|
||||||
if (bufferId == 0) {
|
if (bufferId == 0) {
|
||||||
|
@ -58,7 +50,7 @@ namespace dawn_wire { namespace server {
|
||||||
data->server = this;
|
data->server = this;
|
||||||
data->buffer = ObjectHandle{bufferId, buffer->serial};
|
data->buffer = ObjectHandle{bufferId, buffer->serial};
|
||||||
data->requestSerial = requestSerial;
|
data->requestSerial = requestSerial;
|
||||||
data->size = requestSize;
|
data->size = size;
|
||||||
data->isWrite = isWrite;
|
data->isWrite = isWrite;
|
||||||
|
|
||||||
auto userdata = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(data));
|
auto userdata = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(data));
|
||||||
|
@ -74,27 +66,17 @@ namespace dawn_wire { namespace server {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isWrite) {
|
if (isWrite) {
|
||||||
mProcs.bufferMapWriteAsync(buffer->handle, requestStart, requestSize,
|
mProcs.bufferMapWriteAsync(buffer->handle, start, size, ForwardBufferMapWriteAsync,
|
||||||
ForwardBufferMapWriteAsync, userdata);
|
userdata);
|
||||||
} else {
|
} else {
|
||||||
mProcs.bufferMapReadAsync(buffer->handle, requestStart, requestSize,
|
mProcs.bufferMapReadAsync(buffer->handle, start, size, ForwardBufferMapReadAsync,
|
||||||
ForwardBufferMapReadAsync, userdata);
|
userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::HandleBufferUpdateMappedData(const char** commands, size_t* size) {
|
bool Server::DoBufferUpdateMappedData(ObjectId bufferId, uint32_t count, const uint8_t* data) {
|
||||||
BufferUpdateMappedDataCmd cmd;
|
|
||||||
DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
|
|
||||||
|
|
||||||
if (deserializeResult == DeserializeResult::FatalError) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectId bufferId = cmd.bufferId;
|
|
||||||
size_t dataLength = cmd.dataLength;
|
|
||||||
|
|
||||||
// The null object isn't valid as `self`
|
// The null object isn't valid as `self`
|
||||||
if (bufferId == 0) {
|
if (bufferId == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -102,13 +84,15 @@ namespace dawn_wire { namespace server {
|
||||||
|
|
||||||
auto* buffer = BufferObjects().Get(bufferId);
|
auto* buffer = BufferObjects().Get(bufferId);
|
||||||
if (buffer == nullptr || !buffer->valid || buffer->mappedData == nullptr ||
|
if (buffer == nullptr || !buffer->valid || buffer->mappedData == nullptr ||
|
||||||
buffer->mappedDataSize != dataLength) {
|
buffer->mappedDataSize != count) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_ASSERT(cmd.data != nullptr);
|
if (data == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(buffer->mappedData, cmd.data, dataLength);
|
memcpy(buffer->mappedData, data, count);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
namespace dawn_wire { namespace server {
|
namespace dawn_wire { namespace server {
|
||||||
|
|
||||||
void Server::ForwardDeviceErrorToServer(const char* message, dawnCallbackUserdata userdata) {
|
void Server::ForwardDeviceError(const char* message, dawnCallbackUserdata userdata) {
|
||||||
auto server = reinterpret_cast<Server*>(static_cast<intptr_t>(userdata));
|
auto server = reinterpret_cast<Server*>(static_cast<intptr_t>(userdata));
|
||||||
server->OnDeviceError(message);
|
server->OnDeviceError(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,14 @@
|
||||||
|
|
||||||
namespace dawn_wire { namespace server {
|
namespace dawn_wire { namespace server {
|
||||||
|
|
||||||
bool Server::PostHandleQueueSignal(const QueueSignalCmd& cmd) {
|
bool Server::DoQueueSignal(dawnQueue cSelf, dawnFence cFence, uint64_t signalValue) {
|
||||||
if (cmd.fence == nullptr) {
|
if (cFence == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ObjectId fenceId = FenceObjectIdTable().Get(cmd.fence);
|
|
||||||
|
mProcs.queueSignal(cSelf, cFence, signalValue);
|
||||||
|
|
||||||
|
ObjectId fenceId = FenceObjectIdTable().Get(cFence);
|
||||||
ASSERT(fenceId != 0);
|
ASSERT(fenceId != 0);
|
||||||
auto* fence = FenceObjects().Get(fenceId);
|
auto* fence = FenceObjects().Get(fenceId);
|
||||||
ASSERT(fence != nullptr);
|
ASSERT(fence != nullptr);
|
||||||
|
@ -29,10 +32,10 @@ namespace dawn_wire { namespace server {
|
||||||
auto* data = new FenceCompletionUserdata;
|
auto* data = new FenceCompletionUserdata;
|
||||||
data->server = this;
|
data->server = this;
|
||||||
data->fence = ObjectHandle{fenceId, fence->serial};
|
data->fence = ObjectHandle{fenceId, fence->serial};
|
||||||
data->value = cmd.signalValue;
|
data->value = signalValue;
|
||||||
|
|
||||||
auto userdata = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(data));
|
auto userdata = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(data));
|
||||||
mProcs.fenceOnCompletion(cmd.fence, cmd.signalValue, ForwardFenceCompletedValue, userdata);
|
mProcs.fenceOnCompletion(cFence, signalValue, ForwardFenceCompletedValue, userdata);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue