Add Chromium-only Blender WebEngine parity work
This commit is contained in:
292
blender-5.2.0/intern/cycles/hydra/display_driver.cpp
Normal file
292
blender-5.2.0/intern/cycles/hydra/display_driver.cpp
Normal file
@@ -0,0 +1,292 @@
|
||||
/* SPDX-FileCopyrightText: 2022 NVIDIA Corporation
|
||||
* SPDX-FileCopyrightText: 2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#ifdef _WIN32
|
||||
// Include first to avoid "NOGDI" definition set in Cycles headers
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include "hydra/display_driver.h"
|
||||
#include "hydra/render_buffer.h"
|
||||
#include "hydra/session.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#include <pxr/imaging/hgiGL/texture.h>
|
||||
|
||||
HDCYCLES_NAMESPACE_OPEN_SCOPE
|
||||
|
||||
HdCyclesDisplayDriver::HdCyclesDisplayDriver(HdCyclesSession *renderParam, Hgi *hgi)
|
||||
: _renderParam(renderParam), _hgi(hgi)
|
||||
{
|
||||
}
|
||||
|
||||
HdCyclesDisplayDriver::~HdCyclesDisplayDriver()
|
||||
{
|
||||
if (texture_) {
|
||||
_hgi->DestroyTexture(&texture_);
|
||||
}
|
||||
|
||||
if (gl_pbo_id_) {
|
||||
glDeleteBuffers(1, &gl_pbo_id_);
|
||||
}
|
||||
|
||||
gl_context_dispose();
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::gl_context_create()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!gl_context_) {
|
||||
hdc_ = GetDC(CreateWindowA("STATIC",
|
||||
"HdCycles",
|
||||
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||
0,
|
||||
0,
|
||||
64,
|
||||
64,
|
||||
nullptr,
|
||||
nullptr,
|
||||
GetModuleHandle(nullptr),
|
||||
nullptr));
|
||||
|
||||
int pixelFormat = GetPixelFormat(wglGetCurrentDC());
|
||||
PIXELFORMATDESCRIPTOR pfd = {sizeof(pfd)};
|
||||
DescribePixelFormat((HDC)hdc_, pixelFormat, sizeof(pfd), &pfd);
|
||||
SetPixelFormat((HDC)hdc_, pixelFormat, &pfd);
|
||||
|
||||
TF_VERIFY(gl_context_ = wglCreateContext((HDC)hdc_));
|
||||
TF_VERIFY(wglShareLists(wglGetCurrentContext(), (HGLRC)gl_context_));
|
||||
}
|
||||
if (!gl_context_) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!gl_pbo_id_) {
|
||||
glGenBuffers(1, &gl_pbo_id_);
|
||||
graphics_interop_buffer_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool HdCyclesDisplayDriver::gl_context_enable()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!hdc_ || !gl_context_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mutex_.lock();
|
||||
|
||||
// Do not change context if this is called in the main thread
|
||||
if (wglGetCurrentContext() == nullptr) {
|
||||
if (!TF_VERIFY(wglMakeCurrent((HDC)hdc_, (HGLRC)gl_context_))) {
|
||||
mutex_.unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::gl_context_disable()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (wglGetCurrentContext() == gl_context_) {
|
||||
TF_VERIFY(wglMakeCurrent(nullptr, nullptr));
|
||||
}
|
||||
|
||||
mutex_.unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::gl_context_dispose()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (gl_context_) {
|
||||
TF_VERIFY(wglDeleteContext((HGLRC)gl_context_));
|
||||
DestroyWindow(WindowFromDC((HDC)hdc_));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::next_tile_begin() {}
|
||||
|
||||
bool HdCyclesDisplayDriver::update_begin(const Params ¶ms,
|
||||
int /*texture_width*/,
|
||||
int /*texture_height*/)
|
||||
{
|
||||
if (!gl_context_enable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gl_render_sync_) {
|
||||
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
if (pbo_size_.x != params.full_size.x || pbo_size_.y != params.full_size.y) {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_pbo_id_);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER,
|
||||
sizeof(half4) * params.full_size.x * params.full_size.y,
|
||||
nullptr,
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
pbo_size_ = params.full_size;
|
||||
graphics_interop_buffer_.clear();
|
||||
}
|
||||
|
||||
need_update_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::update_end()
|
||||
{
|
||||
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::flush()
|
||||
{
|
||||
gl_context_enable();
|
||||
|
||||
if (gl_upload_sync_) {
|
||||
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
if (gl_render_sync_) {
|
||||
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
half4 *HdCyclesDisplayDriver::map_texture_buffer()
|
||||
{
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_pbo_id_);
|
||||
|
||||
auto *const mapped_rgba_pixels = static_cast<half4 *>(
|
||||
glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
|
||||
|
||||
if (need_zero_ && mapped_rgba_pixels) {
|
||||
memset(mapped_rgba_pixels, 0, sizeof(half4) * pbo_size_.x * pbo_size_.y);
|
||||
need_zero_ = false;
|
||||
}
|
||||
|
||||
return mapped_rgba_pixels;
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::unmap_texture_buffer()
|
||||
{
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
GraphicsInteropDevice HdCyclesDisplayDriver::graphics_interop_get_device()
|
||||
{
|
||||
GraphicsInteropDevice interop_device;
|
||||
interop_device.type = GraphicsInteropDevice::OPENGL;
|
||||
return interop_device;
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::graphics_interop_update_buffer()
|
||||
{
|
||||
if (graphics_interop_buffer_.is_empty()) {
|
||||
graphics_interop_buffer_.assign(
|
||||
GraphicsInteropDevice::OPENGL, gl_pbo_id_, pbo_size_.x * pbo_size_.y * sizeof(half4));
|
||||
}
|
||||
|
||||
if (need_zero_) {
|
||||
graphics_interop_buffer_.zero();
|
||||
need_zero_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::graphics_interop_activate()
|
||||
{
|
||||
gl_context_enable();
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::graphics_interop_deactivate()
|
||||
{
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::zero()
|
||||
{
|
||||
need_zero_ = true;
|
||||
}
|
||||
|
||||
void HdCyclesDisplayDriver::draw(const Params ¶ms)
|
||||
{
|
||||
auto *const renderBuffer = static_cast<HdCyclesRenderBuffer *>(
|
||||
_renderParam->GetDisplayAovBinding().renderBuffer);
|
||||
if (!renderBuffer || // Ensure this render buffer matches the texture dimensions
|
||||
(renderBuffer->GetWidth() != params.size.x || renderBuffer->GetHeight() != params.size.y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!renderBuffer->IsResourceUsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
gl_context_create();
|
||||
|
||||
// Cycles 'DisplayDriver' only supports 'half4' format
|
||||
TF_VERIFY(renderBuffer->GetFormat() == HdFormatFloat16Vec4);
|
||||
|
||||
const thread_scoped_lock lock(mutex_);
|
||||
|
||||
const GfVec3i dimensions(params.size.x, params.size.y, 1);
|
||||
if (!texture_ || texture_->GetDescriptor().dimensions != dimensions) {
|
||||
if (texture_) {
|
||||
_hgi->DestroyTexture(&texture_);
|
||||
}
|
||||
|
||||
HgiTextureDesc texDesc;
|
||||
texDesc.usage = 0;
|
||||
texDesc.format = HgiFormatFloat16Vec4;
|
||||
texDesc.type = HgiTextureType2D;
|
||||
texDesc.dimensions = dimensions;
|
||||
texDesc.sampleCount = HgiSampleCount1;
|
||||
|
||||
texture_ = _hgi->CreateTexture(texDesc);
|
||||
|
||||
renderBuffer->SetResource(VtValue(texture_));
|
||||
}
|
||||
|
||||
HgiGLTexture *const texture = dynamic_cast<HgiGLTexture *>(texture_.Get());
|
||||
if (!texture || !need_update_ || pbo_size_.x != params.size.x || pbo_size_.y != params.size.y) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gl_upload_sync_) {
|
||||
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->GetTextureId());
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_pbo_id_);
|
||||
glTexSubImage2D(
|
||||
GL_TEXTURE_2D, 0, 0, 0, pbo_size_.x, pbo_size_.y, GL_RGBA, GL_HALF_FLOAT, nullptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
|
||||
need_update_ = false;
|
||||
}
|
||||
|
||||
HDCYCLES_NAMESPACE_CLOSE_SCOPE
|
||||
Reference in New Issue
Block a user