Add placeholder textures to ensure CameraTexture / CameraFeed always have valid RIDs.

This commit is contained in:
bruvzg 2021-08-13 12:32:01 +03:00
parent 39efccf3b8
commit 8f70232a15
3 changed files with 24 additions and 27 deletions

View File

@ -2587,7 +2587,10 @@ RID CameraTexture::get_rid() const {
if (feed.is_valid()) { if (feed.is_valid()) {
return feed->get_texture(which_feed); return feed->get_texture(which_feed);
} else { } else {
return RID(); if (_texture.is_null()) {
_texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
}
return _texture;
} }
} }
@ -2643,5 +2646,7 @@ bool CameraTexture::get_camera_active() const {
CameraTexture::CameraTexture() {} CameraTexture::CameraTexture() {}
CameraTexture::~CameraTexture() { CameraTexture::~CameraTexture() {
// nothing to do here yet if (_texture.is_valid()) {
RenderingServer::get_singleton()->free(_texture);
}
} }

View File

@ -812,6 +812,7 @@ class CameraTexture : public Texture2D {
GDCLASS(CameraTexture, Texture2D); GDCLASS(CameraTexture, Texture2D);
private: private:
mutable RID _texture;
int camera_feed_id = 0; int camera_feed_id = 0;
CameraServer::FeedImage which_feed = CameraServer::FEED_RGBA_IMAGE; CameraServer::FeedImage which_feed = CameraServer::FEED_RGBA_IMAGE;

View File

@ -138,11 +138,15 @@ RID CameraFeed::get_texture(CameraServer::FeedImage p_which) {
CameraFeed::CameraFeed() { CameraFeed::CameraFeed() {
// initialize our feed // initialize our feed
id = CameraServer::get_singleton()->get_free_id(); id = CameraServer::get_singleton()->get_free_id();
base_width = 0;
base_height = 0;
name = "???"; name = "???";
active = false; active = false;
datatype = CameraFeed::FEED_RGB; datatype = CameraFeed::FEED_RGB;
position = CameraFeed::FEED_UNSPECIFIED; position = CameraFeed::FEED_UNSPECIFIED;
transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0);
texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create();
texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create();
} }
CameraFeed::CameraFeed(String p_name, FeedPosition p_position) { CameraFeed::CameraFeed(String p_name, FeedPosition p_position) {
@ -155,16 +159,14 @@ CameraFeed::CameraFeed(String p_name, FeedPosition p_position) {
datatype = CameraFeed::FEED_NOIMAGE; datatype = CameraFeed::FEED_NOIMAGE;
position = p_position; position = p_position;
transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0);
texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create();
texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create();
} }
CameraFeed::~CameraFeed() { CameraFeed::~CameraFeed() {
// Free our textures // Free our textures
if (texture[CameraServer::FEED_Y_IMAGE].is_valid()) { RenderingServer::get_singleton()->free(texture[CameraServer::FEED_Y_IMAGE]);
RenderingServer::get_singleton()->free(texture[CameraServer::FEED_Y_IMAGE]); RenderingServer::get_singleton()->free(texture[CameraServer::FEED_CBCR_IMAGE]);
}
if (texture[CameraServer::FEED_CBCR_IMAGE].is_valid()) {
RenderingServer::get_singleton()->free(texture[CameraServer::FEED_CBCR_IMAGE]);
}
} }
void CameraFeed::set_RGB_img(const Ref<Image> &p_rgb_img) { void CameraFeed::set_RGB_img(const Ref<Image> &p_rgb_img) {
@ -177,12 +179,9 @@ void CameraFeed::set_RGB_img(const Ref<Image> &p_rgb_img) {
// We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot...
base_width = new_width; base_width = new_width;
base_height = new_height; base_height = new_height;
if (texture[CameraServer::FEED_RGBA_IMAGE].is_null()) {
texture[CameraServer::FEED_RGBA_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img); RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img);
} else { RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture);
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img);
RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture);
}
} else { } else {
RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_rgb_img); RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_rgb_img);
} }
@ -201,12 +200,9 @@ void CameraFeed::set_YCbCr_img(const Ref<Image> &p_ycbcr_img) {
// We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot...
base_width = new_width; base_width = new_width;
base_height = new_height; base_height = new_height;
if (texture[CameraServer::FEED_RGBA_IMAGE].is_null()) {
texture[CameraServer::FEED_RGBA_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img); RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img);
} else { RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture);
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img);
RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture);
}
} else { } else {
RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_ycbcr_img); RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_ycbcr_img);
} }
@ -230,16 +226,11 @@ void CameraFeed::set_YCbCr_imgs(const Ref<Image> &p_y_img, const Ref<Image> &p_c
// We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot...
base_width = new_y_width; base_width = new_y_width;
base_height = new_y_height; base_height = new_y_height;
if (texture[CameraServer::FEED_Y_IMAGE].is_null()) { {
texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_y_img);
} else {
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_y_img); RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_y_img);
RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_Y_IMAGE], new_texture); RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_Y_IMAGE], new_texture);
} }
{
if (texture[CameraServer::FEED_CBCR_IMAGE].is_null()) {
texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img);
} else {
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img); RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img);
RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_CBCR_IMAGE], new_texture); RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_CBCR_IMAGE], new_texture);
} }