bool fcExrContext::addLayerTexture(void *tex, fcPixelFormat fmt, int channel, const char *name) { if (m_dev == nullptr) { fcDebugLog("fcExrContext::addLayerTexture(): gfx device is null."); return false; } if (m_task == nullptr) { fcDebugLog("fcExrContext::addLayerTexture(): maybe beginFrame() is not called."); return false; } Buffer *raw_frame = nullptr; if (tex == m_frame_prev) { raw_frame = m_src_prev; fmt = m_fmt_prev; } else { m_frame_prev = tex; m_task->pixels.push_back(Buffer()); raw_frame = &m_task->pixels.back(); raw_frame->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); // get frame buffer if (!m_dev->readTexture(&(*raw_frame)[0], raw_frame->size(), tex, m_task->width, m_task->height, fmt)) { m_task->pixels.pop_back(); return false; } m_src_prev = raw_frame; // convert pixel format if it is not supported by exr if ((fmt & fcPixelFormat_TypeMask) == fcPixelFormat_Type_u8) { m_task->pixels.emplace_back(Buffer()); auto *buf = &m_task->pixels.back(); int channels = fmt & fcPixelFormat_ChannelMask; auto src_fmt = fmt; fmt = fcPixelFormat(fcPixelFormat_Type_f16 | channels); buf->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); fcConvertPixelFormat(&(*buf)[0], fmt, &(*raw_frame)[0], src_fmt, m_task->width * m_task->height); m_src_prev = raw_frame = buf; } m_fmt_prev = fmt; } return addLayerImpl(&(*raw_frame)[0], fmt, channel, name); }
fcAPI int fcAddDeferredCall(const fcDeferredCall& dc, int id) { fcTraceFunc(); if (id <= 0) { // search empty object and return its position if found for (int i = 1; i < (int)g_deferred_calls.size(); ++i) { if (!g_deferred_calls[i]) { g_deferred_calls[i] = dc; return i; } } // 0th is "null" object if (g_deferred_calls.empty()) { g_deferred_calls.emplace_back(fcDeferredCall()); } // allocate new one g_deferred_calls.emplace_back(dc); return (int)g_deferred_calls.size() - 1; } else if(id < (int)g_deferred_calls.size()) { g_deferred_calls[id] = dc; return id; } else { fcDebugLog("fcAddDeferredCall(): should not be here"); return 0; } }
bool fcExrContext::addLayerImpl(char *pixels, fcPixelFormat fmt, int channel, const char *name) { Imf::PixelType pixel_type = Imf::HALF; int channels = fmt & fcPixelFormat_ChannelMask; int tsize = 0; switch (fmt & fcPixelFormat_TypeMask) { case fcPixelFormat_Type_f16: pixel_type = Imf::HALF; tsize = 2; break; case fcPixelFormat_Type_f32: pixel_type = Imf::FLOAT; tsize = 4; break; case fcPixelFormat_Type_i32: pixel_type = Imf::UINT; tsize = 4; break; default: fcDebugLog("fcExrContext::addLayerPixels(): this pixel format is not supported"); return false; } int psize = tsize * channels; m_task->header.channels().insert(name, Imf::Channel(pixel_type)); m_task->frame_buffer.insert(name, Imf::Slice(pixel_type, pixels + (tsize * channel), psize, psize * m_task->width)); return true; }
fcCLinkage fcExport void fcGfxInitializeD3D11(void *device) { if (g_gfx_device != nullptr) { fcDebugLog("fcInitializeD3D11(): already initialized"); return; } g_gfx_device = fcCreateGraphicsDeviceD3D11(device); }
void fcExrContext::endFrameTask(fcExrTaskData *exr) { try { Imf::OutputFile fout(exr->path.c_str(), exr->header); fout.setFrameBuffer(exr->frame_buffer); fout.writePixels(exr->height); delete exr; } catch (std::string &e) { fcDebugLog(e.c_str()); } }
bool fcExrContext::endFrame() { if (m_task == nullptr) { fcDebugLog("fcExrContext::endFrame(): maybe beginFrame() is not called."); return false; } m_frame_prev = nullptr; fcExrTaskData *exr = m_task; m_task = nullptr; ++m_active_task_count; m_tasks.run([this, exr](){ endFrameTask(exr); --m_active_task_count; }); return true; }
bool fcExrContext::beginFrame(const char *path, int width, int height) { if (m_task != nullptr) { fcDebugLog("fcExrContext::beginFrame(): beginFrame() is already called. maybe you forgot to call endFrame()."); return false; } // 実行中のタスクの数が上限に達している場合適当に待つ if (m_active_task_count >= m_conf.max_tasks) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); if (m_active_task_count >= m_conf.max_tasks) { m_tasks.wait(); } } m_task = new fcExrTaskData(path, width, height, m_conf.compression); return true; }
bool fcExrContext::addLayerPixels(const void *pixels, fcPixelFormat fmt, int channel, const char *name) { if (m_task == nullptr) { fcDebugLog("fcExrContext::addLayerPixels(): maybe beginFrame() is not called."); return false; } Buffer *raw_frame = nullptr; if (pixels == m_frame_prev) { raw_frame = m_src_prev; fmt = m_fmt_prev; } else { m_frame_prev = pixels; m_task->pixels.emplace_back(Buffer()); raw_frame = &m_task->pixels.back(); if (m_conf.pixel_format == fcExrPixelFormat::Half) { auto src_fmt = fmt; int channels = fmt & fcPixelFormat_ChannelMask; fmt = fcPixelFormat(fcPixelFormat_Type_f16 | channels); raw_frame->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); if (src_fmt != fmt) { fcConvertPixelFormat(raw_frame->data(), fmt, pixels, src_fmt, m_task->width * m_task->height); } else { memcpy(raw_frame->data(), pixels, raw_frame->size()); } } else if (m_conf.pixel_format == fcExrPixelFormat::Float) { auto src_fmt = fmt; int channels = fmt & fcPixelFormat_ChannelMask; fmt = fcPixelFormat(fcPixelFormat_Type_f32 | channels); raw_frame->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); if (src_fmt != fmt) { fcConvertPixelFormat(raw_frame->data(), fmt, pixels, src_fmt, m_task->width * m_task->height); } else { memcpy(raw_frame->data(), pixels, raw_frame->size()); } } else if (m_conf.pixel_format == fcExrPixelFormat::Int) { auto src_fmt = fmt; int channels = fmt & fcPixelFormat_ChannelMask; fmt = fcPixelFormat(fcPixelFormat_Type_i32 | channels); raw_frame->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); if (src_fmt != fmt) { fcConvertPixelFormat(raw_frame->data(), fmt, pixels, src_fmt, m_task->width * m_task->height); } else { memcpy(raw_frame->data(), pixels, raw_frame->size()); } } else { // adaptive // convert pixel format if it is not supported by exr if ((fmt & fcPixelFormat_TypeMask) == fcPixelFormat_Type_u8) { auto src_fmt = fmt; int channels = fmt & fcPixelFormat_ChannelMask; fmt = fcPixelFormat(fcPixelFormat_Type_f16 | channels); raw_frame->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); fcConvertPixelFormat(raw_frame->data(), fmt, pixels, src_fmt, m_task->width * m_task->height); } else { raw_frame->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); memcpy(raw_frame->data(), pixels, raw_frame->size()); } } m_src_prev = raw_frame; m_fmt_prev = fmt; } return addLayerImpl(raw_frame->data(), fmt, channel, name); }