Skip to content

Commit bed7997

Browse files
committed
client, graphics: fix commandbuffer responses dispatching
1. Modified command buffer response handling to include context and request ID matching 2. Refactored async response processing with improved synchronization mechanisms 3. Updated API signatures to require context and request ID parameters for proper response routing
1 parent 5812c6a commit bed7997

File tree

5 files changed

+187
-75
lines changed

5 files changed

+187
-75
lines changed

src/client/graphics/webgl_context.cpp

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ namespace client_graphics
6666
auto initReq = WebGL1ContextInitCommandBufferRequest();
6767
sendCommandBufferRequest(initReq, true);
6868

69-
initResp = recvCommandBufferResponse<WebGL1ContextInitCommandBufferResponse>(COMMAND_BUFFER_WEBGL_CONTEXT_INIT_RES,
70-
3000);
69+
initResp = recvResponse<WebGL1ContextInitCommandBufferResponse>(COMMAND_BUFFER_WEBGL_CONTEXT_INIT_RES,
70+
initReq,
71+
3000);
7172
if (initResp == nullptr) [[unlikely]]
7273
throw runtime_error("Failed to initialize WebGL context");
7374
}
@@ -246,7 +247,7 @@ namespace client_graphics
246247
// Mark the program as completed.
247248
program->setCompleted(true);
248249
};
249-
recvResponseAsync<LinkProgramCommandBufferResponse>(COMMAND_BUFFER_LINK_PROGRAM_RES, onLinkProgramResponse);
250+
recvResponseAsync<LinkProgramCommandBufferResponse>(COMMAND_BUFFER_LINK_PROGRAM_RES, req, onLinkProgramResponse);
250251

251252
// Mark the program linked successfully.
252253
program->setLinkStatus(true);
@@ -284,8 +285,8 @@ namespace client_graphics
284285
auto req = GetProgramParamCommandBufferRequest(program->id, pname);
285286
sendCommandBufferRequest(req, true);
286287

287-
auto resp = recvCommandBufferResponse<GetProgramParamCommandBufferResponse>(COMMAND_BUFFER_GET_PROGRAM_PARAM_RES);
288-
if (resp != nullptr)
288+
auto resp = recvResponse<GetProgramParamCommandBufferResponse>(COMMAND_BUFFER_GET_PROGRAM_PARAM_RES, req);
289+
if (resp != nullptr) [[likely]]
289290
return resp->value;
290291
else
291292
throw runtime_error("Failed to get program parameter: timeout.");
@@ -303,7 +304,7 @@ namespace client_graphics
303304
auto req = GetProgramInfoLogCommandBufferRequest(program->id);
304305
sendCommandBufferRequest(req, true);
305306

306-
auto resp = recvCommandBufferResponse<GetProgramInfoLogCommandBufferResponse>(COMMAND_BUFFER_GET_PROGRAM_INFO_LOG_RES);
307+
auto resp = recvResponse<GetProgramInfoLogCommandBufferResponse>(COMMAND_BUFFER_GET_PROGRAM_INFO_LOG_RES, req);
307308
if (resp != nullptr) [[likely]]
308309
{
309310
string log(resp->infoLog);
@@ -334,7 +335,8 @@ namespace client_graphics
334335

335336
void WebGLContext::shaderSource(shared_ptr<WebGLShader> shader, const string &source)
336337
{
337-
auto req = ShaderSourceCommandBufferRequest(shader->id, GLSLSourcePatcher2::GetPatchedSource(source));
338+
shader->source = GLSLSourcePatcher2::GetPatchedSource(source);
339+
auto req = ShaderSourceCommandBufferRequest(shader->id, shader->source);
338340
sendCommandBufferRequest(req);
339341
}
340342

@@ -361,8 +363,8 @@ namespace client_graphics
361363
auto req = GetShaderSourceCommandBufferRequest(shader->id);
362364
sendCommandBufferRequest(req, true);
363365

364-
auto resp = recvCommandBufferResponse<GetShaderSourceCommandBufferResponse>(COMMAND_BUFFER_GET_SHADER_SOURCE_RES);
365-
if (resp != nullptr)
366+
auto resp = recvResponse<GetShaderSourceCommandBufferResponse>(COMMAND_BUFFER_GET_SHADER_SOURCE_RES, req);
367+
if (resp != nullptr) [[likely]]
366368
{
367369
string source(resp->source);
368370
delete resp;
@@ -379,8 +381,8 @@ namespace client_graphics
379381
auto req = GetShaderParamCommandBufferRequest(shader->id, pname);
380382
sendCommandBufferRequest(req, true);
381383

382-
auto resp = recvCommandBufferResponse<GetShaderParamCommandBufferResponse>(COMMAND_BUFFER_GET_SHADER_PARAM_RES);
383-
if (resp != nullptr)
384+
auto resp = recvResponse<GetShaderParamCommandBufferResponse>(COMMAND_BUFFER_GET_SHADER_PARAM_RES, req);
385+
if (resp != nullptr) [[likely]]
384386
{
385387
int value = resp->value;
386388
delete resp;
@@ -399,10 +401,18 @@ namespace client_graphics
399401

400402
auto onGetShaderInfoLogResponse = [shader](const GetShaderInfoLogCommandBufferResponse &resp)
401403
{
402-
if (!resp.infoLog.empty())
403-
cerr << "getShaderInfoLog(" << shader->id << "): " << resp.infoLog << endl;
404+
if (!resp.infoLog.empty() && resp.infoLog.find("ERROR:") == 0)
405+
{
406+
// TODO(yorkie): print to console domain in inspector.
407+
cerr << "Shader(" << shader->id << ") compilation error:" << endl
408+
<< resp.infoLog << endl
409+
<< "============== shader source ==============" << endl
410+
<< shader->source << endl
411+
<< "============================================" << endl;
412+
}
404413
};
405414
recvResponseAsync<GetShaderInfoLogCommandBufferResponse>(COMMAND_BUFFER_GET_SHADER_INFO_LOG_RES,
415+
req,
406416
onGetShaderInfoLogResponse);
407417

408418
// Return an empty string directly, and the response will be logged in the async callback.
@@ -534,8 +544,9 @@ namespace client_graphics
534544
auto req = CheckFramebufferStatusCommandBufferRequest(static_cast<uint32_t>(target));
535545
sendCommandBufferRequest(req, true);
536546

537-
auto resp = recvCommandBufferResponse<CheckFramebufferStatusCommandBufferResponse>(COMMAND_BUFFER_CHECK_FRAMEBUFFER_STATUS_RES);
538-
if (resp != nullptr)
547+
auto resp = recvResponse<CheckFramebufferStatusCommandBufferResponse>(
548+
COMMAND_BUFFER_CHECK_FRAMEBUFFER_STATUS_RES, req);
549+
if (resp != nullptr) [[likely]]
539550
{
540551
uint32_t r = resp->status;
541552
delete resp;
@@ -1409,8 +1420,8 @@ namespace client_graphics
14091420
auto req = GetBooleanvCommandBufferRequest(static_cast<uint32_t>(pname));
14101421
sendCommandBufferRequest(req, true);
14111422

1412-
auto resp = recvCommandBufferResponse<GetBooleanvCommandBufferResponse>(COMMAND_BUFFER_GET_BOOLEANV_RES);
1413-
if (resp == nullptr)
1423+
auto resp = recvResponse<GetBooleanvCommandBufferResponse>(COMMAND_BUFFER_GET_BOOLEANV_RES, req);
1424+
if (resp == nullptr) [[unlikely]]
14141425
{
14151426
string msg = "Failed to get boolean parameter(" + to_string(static_cast<uint32_t>(pname)) + "): timeout.";
14161427
throw runtime_error(msg);
@@ -1475,8 +1486,8 @@ namespace client_graphics
14751486
auto req = GetIntegervCommandBufferRequest(static_cast<uint32_t>(pname));
14761487
sendCommandBufferRequest(req, true);
14771488

1478-
auto resp = recvCommandBufferResponse<GetIntegervCommandBufferResponse>(COMMAND_BUFFER_GET_INTEGERV_RES);
1479-
if (resp == nullptr)
1489+
auto resp = recvResponse<GetIntegervCommandBufferResponse>(COMMAND_BUFFER_GET_INTEGERV_RES, req);
1490+
if (resp == nullptr) [[unlikely]]
14801491
throw runtime_error("Failed to get integer parameter: timeout.");
14811492

14821493
int v = resp->value;
@@ -1514,8 +1525,8 @@ namespace client_graphics
15141525
auto req = GetStringCommandBufferRequest(static_cast<uint32_t>(pname));
15151526
sendCommandBufferRequest(req, true);
15161527

1517-
auto resp = recvCommandBufferResponse<GetStringCommandBufferResponse>(COMMAND_BUFFER_GET_STRING_RES);
1518-
if (resp == nullptr)
1528+
auto resp = recvResponse<GetStringCommandBufferResponse>(COMMAND_BUFFER_GET_STRING_RES, req);
1529+
if (resp == nullptr) [[unlikely]]
15191530
{
15201531
string msg = "Failed to get string parameter(" + to_string(static_cast<uint32_t>(pname)) + "): timeout.";
15211532
throw runtime_error(msg);
@@ -1549,8 +1560,9 @@ namespace client_graphics
15491560
auto req = GetShaderPrecisionFormatCommandBufferRequest(shadertype, precisiontype);
15501561
sendCommandBufferRequest(req, true);
15511562

1552-
auto resp = recvCommandBufferResponse<GetShaderPrecisionFormatCommandBufferResponse>(COMMAND_BUFFER_GET_SHADER_PRECISION_FORMAT_RES);
1553-
if (resp == nullptr)
1563+
auto resp = recvResponse<GetShaderPrecisionFormatCommandBufferResponse>(
1564+
COMMAND_BUFFER_GET_SHADER_PRECISION_FORMAT_RES, req);
1565+
if (resp == nullptr) [[unlikely]]
15541566
throw runtime_error("Failed to get shader precision format: timeout.");
15551567

15561568
WebGLShaderPrecisionFormat format(*resp);
@@ -1576,8 +1588,8 @@ namespace client_graphics
15761588
auto req = GetExtensionsCommandBufferRequest();
15771589
sendCommandBufferRequest(req, true);
15781590

1579-
extensionsResp = recvCommandBufferResponse<GetExtensionsCommandBufferResponse>(COMMAND_BUFFER_GET_EXTENSIONS_RES);
1580-
if (extensionsResp == nullptr)
1591+
extensionsResp = recvResponse<GetExtensionsCommandBufferResponse>(COMMAND_BUFFER_GET_EXTENSIONS_RES, req);
1592+
if (extensionsResp == nullptr) [[unlikely]]
15811593
throw runtime_error("Failed to get supported extensions: timeout.");
15821594
}
15831595

@@ -1672,8 +1684,8 @@ namespace client_graphics
16721684
sendCommandBufferRequest(req, true);
16731685

16741686
// Wait for the context init response
1675-
initResp = recvCommandBufferResponse<WebGL2ContextInitCommandBufferResponse>(COMMAND_BUFFER_WEBGL2_CONTEXT_INIT_RES);
1676-
if (initResp == nullptr)
1687+
initResp = recvResponse<WebGL2ContextInitCommandBufferResponse>(COMMAND_BUFFER_WEBGL2_CONTEXT_INIT_RES, req);
1688+
if (initResp == nullptr) [[unlikely]]
16771689
throw runtime_error("Failed to initialize WebGL2 context: timeout.");
16781690
}
16791691

@@ -2083,8 +2095,8 @@ namespace client_graphics
20832095
auto req = GetIntegervCommandBufferRequest(static_cast<uint32_t>(pname));
20842096
sendCommandBufferRequest(req, true);
20852097

2086-
auto resp = recvCommandBufferResponse<GetIntegervCommandBufferResponse>(COMMAND_BUFFER_GET_INTEGERV_RES);
2087-
if (resp == nullptr)
2098+
auto resp = recvResponse<GetIntegervCommandBufferResponse>(COMMAND_BUFFER_GET_INTEGERV_RES, req);
2099+
if (resp == nullptr) [[unlikely]]
20882100
throw runtime_error("Failed to get integer parameter: timeout.");
20892101

20902102
int v = resp->value;

src/client/graphics/webgl_context.hpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,12 +606,24 @@ namespace client_graphics
606606
*/
607607
bool sendCommandBufferRequest(commandbuffers::TrCommandBufferBase &commandBuffer, bool followsFlush = false);
608608

609+
/**
610+
* Receives a command buffer response from the server, and returns the response as a pointer to the specified type.
611+
*
612+
* @param responseType The type of the response command buffer, that is used to check the response type.
613+
* @param req The request command buffer that is used to match the response.
614+
* @param timeout The timeout in milliseconds to wait for the response, default is 1000ms.
615+
* @returns A pointer to the response command buffer of the specified type, or nullptr if the response is not
616+
* received within the timeout or if the response type does not match.
617+
*/
609618
template <typename R>
610-
R *recvCommandBufferResponse(commandbuffers::CommandBufferType responseType, int timeout = 1000)
619+
R *recvResponse(commandbuffers::CommandBufferType responseType,
620+
const commandbuffers::TrCommandBufferBase &req,
621+
int timeout = 1000)
611622
{
612-
auto response = clientContext_->recvCommandBufferResponse(timeout);
623+
auto response = clientContext_->recvCommandBufferResponse(this, req.id, timeout);
613624
if (response == nullptr) [[unlikely]]
614625
return nullptr;
626+
615627
if (response->type != responseType) [[unlikely]]
616628
{
617629
std::cerr << "recvCommandBuffer(): "
@@ -622,8 +634,17 @@ namespace client_graphics
622634
return dynamic_cast<R *>(response);
623635
}
624636

637+
/**
638+
* It receives a command buffer response **asynchronously**, and calls the callback function with the response.
639+
*
640+
* @param responseType The type of the response command buffer, that is used to check the response type.
641+
* @param req The request command buffer that is used to match the response.
642+
* @param callback The callback function that is called with the response command buffer of the specified type.
643+
*/
625644
template <typename R>
626-
void recvResponseAsync(commandbuffers::CommandBufferType responseType, std::function<void(const R &)> callback)
645+
void recvResponseAsync(commandbuffers::CommandBufferType responseType,
646+
const commandbuffers::TrCommandBufferBase &req,
647+
std::function<void(const R &)> callback)
627648
{
628649
auto onResponse = [responseType, callback](const commandbuffers::TrCommandBufferBase &response)
629650
{
@@ -636,7 +657,7 @@ namespace client_graphics
636657
}
637658
callback(dynamic_cast<const R &>(response));
638659
};
639-
clientContext_->recvCommandBufferResponseAsync(onResponse);
660+
clientContext_->recvCommandBufferResponseAsync(this, req.id, onResponse);
640661
}
641662

642663
bool sendFlushCommand(std::shared_ptr<client_xr::XRSession> session);

src/client/graphics/webgl_shader.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#pragma once
22

33
#include <map>
4+
#include <string>
5+
46
#include "common/command_buffers/details/program.hpp"
57
#include "./webgl_object.hpp"
68

@@ -23,5 +25,6 @@ namespace client_graphics
2325

2426
public:
2527
WebGLShaderType type;
28+
std::string source;
2629
};
2730
}

0 commit comments

Comments
 (0)