Пример #1
0
static bool texrender_resetbuffer(gs_texrender_t texrender, uint32_t cx,
		uint32_t cy)
{
	if (!texrender)
		return false;

	gs_texture_destroy(texrender->target);
	gs_zstencil_destroy(texrender->zs);

	texrender->target = NULL;
	texrender->zs     = NULL;
	texrender->cx     = cx;
	texrender->cy     = cy;

	texrender->target = gs_texture_create(cx, cy, texrender->format,
			1, NULL, GS_RENDER_TARGET);
	if (!texrender->target)
		return false;

	if (texrender->zsformat != GS_ZS_NONE) {
		texrender->zs = gs_zstencil_create(cx, cy, texrender->zsformat);
		if (!texrender->zs) {
			gs_texture_destroy(texrender->target);
			texrender->target = NULL;

			return false;
		}
	}

	return true;
}
Пример #2
0
/**
 * Resize the texture
 *
 * This will automatically create the texture if it does not exist
 *
 * @note requires to be called within the obs graphics context
 */
static inline void xshm_resize_texture(struct xshm_data *data)
{
	if (data->texture)
		gs_texture_destroy(data->texture);
	data->texture = gs_texture_create(data->width, data->height,
		GS_BGRA, 1, NULL, GS_DYNAMIC);
}
Пример #3
0
/**
 * Stop the capture
 */
static void xshm_capture_stop(struct xshm_data *data)
{
	obs_enter_graphics();

	if (data->texture) {
		gs_texture_destroy(data->texture);
		data->texture = NULL;
	}
	if (data->cursor) {
		xcb_xcursor_destroy(data->cursor);
		data->cursor = NULL;
	}

	obs_leave_graphics();

	if (data->xshm) {
		xshm_xcb_detach(data->xshm);
		data->xshm = NULL;
	}

	if (data->xcb) {
		xcb_disconnect(data->xcb);
		data->xcb = NULL;
	}

	if (data->server) {
		bfree(data->server);
		data->server = NULL;
	}
}
Пример #4
0
/**
 * Stop the capture
 */
static void xshm_capture_stop(struct xshm_data *data)
{
	obs_enter_graphics();

	if (data->texture) {
		gs_texture_destroy(data->texture);
		data->texture = NULL;
	}
	if (data->cursor) {
		xcursor_destroy(data->cursor);
		data->cursor = NULL;
	}

	obs_leave_graphics();

	if (data->xshm) {
		xshm_detach(data->xshm);
		data->xshm = NULL;
	}

	if (data->dpy) {
		XSync(data->dpy, true);
		XCloseDisplay(data->dpy);
		data->dpy = NULL;
	}

	if (data->server) {
		bfree(data->server);
		data->server = NULL;
	}
}
Пример #5
0
static void xcc_cleanup(XCompcapMain_private *p)
{
	PLock lock(&p->lock);
	XDisplayLock xlock;

	if (p->gltex) {
		gs_texture_destroy(p->gltex);
		p->gltex = 0;
	}

	if (p->glxpixmap) {
		glXDestroyPixmap(xdisp, p->glxpixmap);
		p->glxpixmap = 0;
	}

	if (p->pixmap) {
		XFreePixmap(xdisp, p->pixmap);
		p->pixmap = 0;
	}

	if (p->win) {
		XCompositeUnredirectWindow(xdisp, p->win,
				CompositeRedirectAutomatic);
		XSelectInput(xdisp, p->win, 0);
		p->win = 0;
	}
}
Пример #6
0
void gs_texrender_destroy(gs_texrender_t texrender)
{
	if (texrender) {
		gs_texture_destroy(texrender->target);
		gs_zstencil_destroy(texrender->zs);
		bfree(texrender);
	}
}
Пример #7
0
	inline void DestroyTextures()
	{
		if (texture) {
			obs_enter_graphics();
			gs_texture_destroy(texture);
			texture = nullptr;
			obs_leave_graphics();
		}
	}
static void disable_deinterlacing(obs_source_t *source)
{
	obs_enter_graphics();
	gs_texture_destroy(source->async_prev_texture);
	gs_texrender_destroy(source->async_prev_texrender);
	source->deinterlace_mode = OBS_DEINTERLACE_MODE_DISABLE;
	source->async_prev_texture = NULL;
	source->async_prev_texrender = NULL;
	obs_leave_graphics();
}
Пример #9
0
/**
 * Resize the texture
 *
 * This will automatically create the texture if it does not exist
 */
static void xshm_resize_texture(struct xshm_data *data)
{
	obs_enter_graphics();

	if (data->texture)
		gs_texture_destroy(data->texture);
	data->texture = gs_texture_create(data->width, data->height,
		GS_BGRA, 1, NULL, GS_DYNAMIC);

	obs_leave_graphics();
}
void BrowserSource::Impl::Listener::DestroySurface(
		BrowserSurfaceHandle surfaceHandle)
{
	if (textureSet.count(surfaceHandle) == 1) {
		obs_enter_graphics();
		textureSet.erase(surfaceHandle);
		gs_texture_destroy(surfaceHandle);
		browserSource->activeTexture = nullptr;
		obs_leave_graphics();
	}
}
Пример #11
0
static void obs_free_video(void)
{
	struct obs_core_video *video = &obs->video;

	if (video->video) {
		obs_display_free(&video->main_display);

		video_output_close(video->video);
		video->video = NULL;

		if (!video->graphics)
			return;

		gs_enter_context(video->graphics);

		if (video->mapped_surface) {
			gs_stagesurface_unmap(video->mapped_surface);
			video->mapped_surface = NULL;
		}

		for (size_t i = 0; i < NUM_TEXTURES; i++) {
			gs_stagesurface_destroy(video->copy_surfaces[i]);
			gs_texture_destroy(video->render_textures[i]);
			gs_texture_destroy(video->convert_textures[i]);
			gs_texture_destroy(video->output_textures[i]);
			obs_source_frame_free(&video->convert_frames[i]);

			video->copy_surfaces[i]    = NULL;
			video->render_textures[i]  = NULL;
			video->convert_textures[i] = NULL;
			video->output_textures[i]  = NULL;
		}

		gs_leave_context();

		circlebuf_free(&video->timestamp_buffer);

		video->cur_texture = 0;
	}
}
Пример #12
0
void dc_capture_free(struct dc_capture *capture)
{
	if (capture->hdc) {
		SelectObject(capture->hdc, capture->old_bmp);
		DeleteDC(capture->hdc);
		DeleteObject(capture->bmp);
	}

	obs_enter_graphics();
	gs_texture_destroy(capture->texture);
	obs_leave_graphics();

	memset(capture, 0, sizeof(struct dc_capture));
}
Пример #13
0
static void ft2_source_destroy(void *data)
{
	struct ft2_source *srcdata = data;

	if (srcdata->font_face != NULL) {
		FT_Done_Face(srcdata->font_face);
		srcdata->font_face = NULL;
	}
	
	for (uint32_t i = 0; i < num_cache_slots; i++) {
		if (srcdata->cacheglyphs[i] != NULL) {
			bfree(srcdata->cacheglyphs[i]);
			srcdata->cacheglyphs[i] = NULL;
		}
	}

	if (srcdata->font_name != NULL)
		bfree(srcdata->font_name);
	if (srcdata->font_style != NULL)
		bfree(srcdata->font_style);
	if (srcdata->text != NULL)
		bfree(srcdata->text);
	if (srcdata->texbuf != NULL)
		bfree(srcdata->texbuf);
	if (srcdata->colorbuf != NULL)
		bfree(srcdata->colorbuf);
	if (srcdata->text_file != NULL)
		bfree(srcdata->text_file);

	obs_enter_graphics();

	if (srcdata->tex != NULL) {
		gs_texture_destroy(srcdata->tex);
		srcdata->tex = NULL;
	}
	if (srcdata->vbuf != NULL) {
		gs_vertexbuffer_destroy(srcdata->vbuf);
		srcdata->vbuf = NULL;
	}
	if (srcdata->draw_effect != NULL) {
		gs_effect_destroy(srcdata->draw_effect);
		srcdata->draw_effect = NULL;
	}

	obs_leave_graphics();

	bfree(srcdata);
}
Пример #14
0
XCompcapMain::~XCompcapMain()
{
	ObsGsContextHolder obsctx;

	if (p->tex) {
		gs_texture_destroy(p->tex);
		p->tex = 0;
	}

	xcc_cleanup(p);

	if (p->cursor) {
		xcursor_destroy(p->cursor);
		p->cursor = nullptr;
	}

	delete p;
}
Пример #15
0
void gs_image_file_free(gs_image_file_t *image)
{
	if (!image)
		return;

	if (image->loaded) {
		if (image->is_animated_gif) {
			gif_finalise(&image->gif);
			bfree(image->animation_frame_cache);
			bfree(image->animation_frame_data);
		}

		gs_texture_destroy(image->texture);
	}

	bfree(image->texture_data);
	bfree(image->gif_data);
	memset(image, 0, sizeof(*image));
}
Пример #16
0
/*
 * Create the cursor texture, either by updating if the new cursor has the same
 * size or by creating a new texture if the size is different
 */
static void xcursor_create(xcursor_t *data, XFixesCursorImage *xc) {
	uint32_t *pixels = xcursor_pixels(xc);

	if (data->tex
	&& data->last_height == xc->width
	&& data->last_width == xc->height) {
		gs_texture_set_image(data->tex, (const uint8_t *) pixels,
			xc->width * sizeof(uint32_t), False);
	} else {
		if (data->tex)
			gs_texture_destroy(data->tex);

		data->tex = gs_texture_create(xc->width, xc->height,
			GS_BGRA, 1, (const uint8_t **) &pixels, GS_DYNAMIC);
	}

	bfree(pixels);

	data->last_serial = xc->cursor_serial;
	data->last_width = xc->width;
	data->last_height = xc->height;
}
Пример #17
0
/**
 * Destroy the capture
 */
static void xshm_destroy(void *vptr)
{
	XSHM_DATA(vptr);

	if (!data)
		return;

	obs_enter_graphics();

	if (data->texture)
		gs_texture_destroy(data->texture);
	if (data->cursor)
		xcursor_destroy(data->cursor);

	obs_leave_graphics();

	if (data->xshm)
		xshm_detach(data->xshm);
	if (data->dpy)
		XCloseDisplay(data->dpy);

	bfree(data);
}
Пример #18
0
/*
 * Create the cursor texture, either by updating if the new cursor has the same
 * size or by creating a new texture if the size is different
 */
static void xcb_xcursor_create(xcb_xcursor_t *data,
		xcb_xfixes_get_cursor_image_reply_t *xc)
{
	uint32_t *pixels = xcb_xfixes_get_cursor_image_cursor_image(xc);
	if (!pixels)
		return;

	if (data->tex && data->last_height == xc->width &&
			data->last_width == xc->height) {
		gs_texture_set_image(data->tex, (const uint8_t *) pixels,
			xc->width * sizeof(uint32_t), false);
	} else {
		if (data->tex)
			gs_texture_destroy(data->tex);

		data->tex = gs_texture_create(xc->width, xc->height,
			GS_BGRA, 1, (const uint8_t **) &pixels, GS_DYNAMIC);
	}

	data->last_serial = xc->cursor_serial;
	data->last_width  = xc->width;
	data->last_height = xc->height;
}
Пример #19
0
void xcursor_destroy(xcursor_t *data) {
	if (data->tex)
		gs_texture_destroy(data->tex);
	bfree(data);
}
Пример #20
0
void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs)
{
	FT_GlyphSlot slot = 0;
	FT_UInt glyph_index = 0;

	if (!srcdata->font_face || !cache_glyphs)
		return;

	//slot = srcdata->font_face->glyph;

	uint32_t dx = srcdata->texbuf_x, dy = srcdata->texbuf_y;
	uint8_t alpha;

	int32_t cached_glyphs = 0;
	size_t len = wcslen(cache_glyphs);

	for (size_t i = 0; i < len; i++) {
		FT_Face curFace;
		glyph_index = FT_Get_Char_Index_Fallback(srcdata, &curFace,
			cache_glyphs[i]);

		if (curFace == 0)
			goto skip_glyph;

		slot = curFace->glyph;

		if (src_glyph != NULL)
			goto skip_glyph;

		FT_Load_Glyph(curFace, glyph_index, FT_LOAD_DEFAULT);

		bool isUseFallback = slot->face == srcdata->fallback_face;
		bool shouldBolden = ((!isUseFallback && srcdata->fake_bold) || (isUseFallback && srcdata->fallback_fake_bold));

		if (slot->format == FT_GLYPH_FORMAT_OUTLINE && shouldBolden)
			FT_Outline_EmboldenXY(&slot->outline, 0x80, 0x40);

		FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);

		uint32_t g_w = slot->bitmap.width;
		uint32_t g_h = slot->bitmap.rows;

		if (srcdata->max_h < g_h) srcdata->max_h = g_h;

		if (dx + g_w >= texbuf_w) {
			dx = 0;
			dy += srcdata->max_h + 1;
		}

		src_glyph = bzalloc(sizeof(struct glyph_info));
		src_glyph->u = (float)dx / (float)texbuf_w;
		src_glyph->u2 = (float)(dx + g_w) / (float)texbuf_w;
		src_glyph->v = (float)dy / (float)texbuf_h;
		src_glyph->v2 = (float)(dy + g_h) / (float)texbuf_h;
		src_glyph->w = g_w;
		src_glyph->h = g_h;
		src_glyph->yoff = slot->bitmap_top;
		src_glyph->xoff = slot->bitmap_left;
		src_glyph->xadv = slot->advance.x >> 6;

		for (uint32_t y = 0; y < g_h; y++) {
			for (uint32_t x = 0; x < g_w; x++) {
				alpha = slot->bitmap.buffer[glyph_pos];
				srcdata->texbuf[buf_pos] =
					0x00FFFFFF ^ ((uint32_t)alpha << 24);
			}
		}

		dx += (g_w + 1);
		if (dx >= texbuf_w) {
			dx = 0;
			dy += srcdata->max_h;
		}

		cached_glyphs++;
	skip_glyph:;
	}

	srcdata->texbuf_x = dx;
	srcdata->texbuf_y = dy;

	if (cached_glyphs > 0) {

		obs_enter_graphics();

		if (srcdata->tex != NULL) {
			gs_texture_t *tmp_texture = NULL;
			tmp_texture = srcdata->tex;
			srcdata->tex = NULL;
			gs_texture_destroy(tmp_texture);
		}

		srcdata->tex = gs_texture_create(texbuf_w, texbuf_h,
			GS_RGBA, 1, (const uint8_t **)&srcdata->texbuf, 0);

		obs_leave_graphics();
	}
}
Пример #21
0
void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs)
{
	FT_GlyphSlot slot;
	FT_UInt glyph_index = 0;

	if (!srcdata->font_face)
		return;

	slot = srcdata->font_face->glyph;

	uint32_t dx = srcdata->texbuf_x, dy = srcdata->texbuf_y;
	uint8_t alpha;

	int32_t cached_glyphs = 0;

	for (uint32_t i = 0; i < wcslen(cache_glyphs); i++) {
		glyph_index = FT_Get_Char_Index(srcdata->font_face,
			cache_glyphs[i]);

		if (src_glyph != NULL)
			goto skip_glyph;

		FT_Load_Glyph(srcdata->font_face, glyph_index, FT_LOAD_DEFAULT);
		FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);

		uint32_t g_w = slot->bitmap.width;
		uint32_t g_h = slot->bitmap.rows;

		if (srcdata->max_h < g_h) srcdata->max_h = g_h;

		if (dx + g_w >= texbuf_w) {
			dx = 0;
			dy += srcdata->max_h + 1;
		}

		src_glyph = bzalloc(sizeof(struct glyph_info));
		src_glyph->u = (float)dx / (float)texbuf_w;
		src_glyph->u2 = (float)(dx + g_w) / (float)texbuf_w;
		src_glyph->v = (float)dy / (float)texbuf_h;
		src_glyph->v2 = (float)(dy + g_h) / (float)texbuf_h;
		src_glyph->w = g_w;
		src_glyph->h = g_h;
		src_glyph->yoff = slot->bitmap_top;
		src_glyph->xoff = slot->bitmap_left;
		src_glyph->xadv = slot->advance.x >> 6;

		for (uint32_t y = 0; y < g_h; y++) {
			for (uint32_t x = 0; x < g_w; x++) {
				alpha = slot->bitmap.buffer[glyph_pos];
				srcdata->texbuf[buf_pos] =
					0x00FFFFFF ^ (alpha << 24);
			}
		}

		dx += (g_w + 1);
		if (dx >= texbuf_w) {
			dx = 0;
			dy += srcdata->max_h;
		}

		cached_glyphs++;
	skip_glyph:;
	}

	srcdata->texbuf_x = dx;
	srcdata->texbuf_y = dy;

	if (cached_glyphs > 0) {

		obs_enter_graphics();

		if (srcdata->tex != NULL) {
			gs_texture_t tmp_texture = NULL;
			tmp_texture = srcdata->tex;
			srcdata->tex = NULL;
			gs_texture_destroy(tmp_texture);
		}

		srcdata->tex = gs_texture_create(texbuf_w, texbuf_h,
			GS_RGBA, 1, (const uint8_t **)&srcdata->texbuf, 0);

		obs_leave_graphics();
	}
}
Пример #22
0
void XCompcapMain::updateSettings(obs_data_t *settings)
{
	PLock lock(&p->lock);
	XErrorLock xlock;
	ObsGsContextHolder obsctx;

	blog(LOG_DEBUG, "Settings updating");

	Window prevWin = p->win;

	xcc_cleanup(p);

	if (settings) {
		const char *windowName = obs_data_get_string(settings,
				"capture_window");

		p->windowName = windowName;
		p->win = getWindowFromString(windowName);

		p->cut_top = obs_data_get_int(settings, "cut_top");
		p->cut_left = obs_data_get_int(settings, "cut_left");
		p->cut_right = obs_data_get_int(settings, "cut_right");
		p->cut_bot = obs_data_get_int(settings, "cut_bot");
		p->lockX = obs_data_get_bool(settings, "lock_x");
		p->swapRedBlue = obs_data_get_bool(settings, "swap_redblue");
		p->show_cursor = obs_data_get_bool(settings, "show_cursor");
		p->include_border = obs_data_get_bool(settings, "include_border");
		p->exclude_alpha = obs_data_get_bool(settings, "exclude_alpha");
	} else {
		p->win = prevWin;
	}

	xlock.resetError();

	if (p->win)
		XCompositeRedirectWindow(xdisp, p->win,
				CompositeRedirectAutomatic);

	if (xlock.gotError()) {
		blog(LOG_ERROR, "XCompositeRedirectWindow failed: %s",
				xlock.getErrorText().c_str());
		return;
	}

	if (p->win)
		XSelectInput(xdisp, p->win, StructureNotifyMask | ExposureMask);
	XSync(xdisp, 0);

	XWindowAttributes attr;
	if (!p->win || !XGetWindowAttributes(xdisp, p->win, &attr)) {
		p->win = 0;
		p->width = 0;
		p->height = 0;
		return;
	}

	if (p->win && p->cursor && p->show_cursor) {
		Window child;
		int x, y;

		XTranslateCoordinates(xdisp, p->win, attr.root, 0, 0, &x, &y,
				&child);
		xcursor_offset(p->cursor, x, y);
	}

	gs_color_format cf = GS_RGBA;

	if (p->exclude_alpha) {
		cf = GS_BGRX;
	}

	p->border = attr.border_width;

	if (p->include_border) {
		p->width = attr.width + p->border * 2;
		p->height = attr.height + p->border * 2;
	} else {
		p->width = attr.width;
		p->height = attr.height;
	}

	if (p->cut_top + p->cut_bot < (int)p->height) {
		p->cur_cut_top = p->cut_top;
		p->cur_cut_bot = p->cut_bot;
	} else {
		p->cur_cut_top = 0;
		p->cur_cut_bot = 0;
	}

	if (p->cut_left + p->cut_right < (int)p->width) {
		p->cur_cut_left = p->cut_left;
		p->cur_cut_right = p->cut_right;
	} else {
		p->cur_cut_left = 0;
		p->cur_cut_right = 0;
	}

	if (p->tex)
		gs_texture_destroy(p->tex);

	uint8_t *texData = new uint8_t[width() * height() * 4];

	memset(texData, 0, width() * height() * 4);

	const uint8_t* texDataArr[] = { texData, 0 };

	p->tex = gs_texture_create(width(), height(), cf, 1,
			texDataArr, 0);

	delete[] texData;

	if (p->swapRedBlue) {
		GLuint tex = *(GLuint*)gs_texture_get_obj(p->tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	const int attrs[] =
	{
		GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE,
		GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
		GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
		GLX_DOUBLEBUFFER, GL_FALSE,
		None
	};

	int nelem = 0;
	GLXFBConfig* configs = glXChooseFBConfig(xdisp,
			XCompcap::getRootWindowScreen(attr.root),
			attrs, &nelem);

	if (nelem <= 0) {
		blog(LOG_ERROR, "no matching fb config found");
		p->win = 0;
		p->height = 0;
		p->width = 0;
		return;
	}

	glXGetFBConfigAttrib(xdisp, configs[0], GLX_Y_INVERTED_EXT, &nelem);
	p->inverted = nelem != 0;

	xlock.resetError();

	p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win);

	if (xlock.gotError()) {
		blog(LOG_ERROR, "XCompositeNameWindowPixmap failed: %s",
				xlock.getErrorText().c_str());
		p->pixmap = 0;
		XFree(configs);
		return;
	}

	const int attribs[] =
	{
		GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
		GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
		None
	};

	p->glxpixmap = glXCreatePixmap(xdisp, configs[0], p->pixmap, attribs);

	if (xlock.gotError()) {
		blog(LOG_ERROR, "glXCreatePixmap failed: %s",
				xlock.getErrorText().c_str());
		XFreePixmap(xdisp, p->pixmap);
		XFree(configs);
		p->pixmap = 0;
		p->glxpixmap = 0;
		return;
	}

	XFree(configs);

	p->gltex = gs_texture_create(p->width, p->height, cf, 1, 0,
			GS_GL_DUMMYTEX);

	GLuint gltex = *(GLuint*)gs_texture_get_obj(p->gltex);
	glBindTexture(GL_TEXTURE_2D, gltex);
	glXBindTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}