Exemple #1
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);
}
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;
}
void gs_image_file_init_texture(gs_image_file_t *image)
{
	if (!image->loaded)
		return;

	if (image->is_animated_gif) {
		image->texture = gs_texture_create(
				image->cx, image->cy, image->format, 1,
				(const uint8_t**)&image->gif.frame_image,
				GS_DYNAMIC);

	} else {
		image->texture = gs_texture_create(
				image->cx, image->cy, image->format, 1,
				(const uint8_t**)&image->texture_data, 0);
		bfree(image->texture_data);
		image->texture_data = NULL;
	}
}
/**
 * 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 set_deinterlace_texture_size(obs_source_t *source)
{
	if (source->async_gpu_conversion) {
		source->async_prev_texrender =
			gs_texrender_create(GS_BGRX, GS_ZS_NONE);

		source->async_prev_texture = gs_texture_create(
				source->async_convert_width,
				source->async_convert_height,
				source->async_texture_format,
				1, NULL, GS_DYNAMIC);

	} else {
		enum gs_color_format format = convert_video_format(
				source->async_format);

		source->async_prev_texture = gs_texture_create(
				source->async_width, source->async_height,
				format, 1, NULL, GS_DYNAMIC);
	}
}
Exemple #6
0
static bool obs_init_textures(struct obs_video_info *ovi)
{
	struct obs_core_video *video = &obs->video;
	bool yuv = format_is_yuv(ovi->output_format);
	uint32_t output_height = video->gpu_conversion ?
		video->conversion_height : ovi->output_height;
	size_t i;

	for (i = 0; i < NUM_TEXTURES; i++) {
		video->copy_surfaces[i] = gs_stagesurface_create(
				ovi->output_width, output_height, GS_RGBA);

		if (!video->copy_surfaces[i])
			return false;

		video->render_textures[i] = gs_texture_create(
				ovi->base_width, ovi->base_height,
				GS_RGBA, 1, NULL, GS_RENDER_TARGET);

		if (!video->render_textures[i])
			return false;

		video->output_textures[i] = gs_texture_create(
				ovi->output_width, ovi->output_height,
				GS_RGBA, 1, NULL, GS_RENDER_TARGET);

		if (!video->output_textures[i])
			return false;

		if (yuv)
			obs_source_frame_init(&video->convert_frames[i],
					ovi->output_format,
					ovi->output_width,ovi->output_height);
	}

	return true;
}
bool BrowserSource::Impl::Listener::CreatePopupSurface(int width, int height,
	int x, int y, BrowserSurfaceHandle *popupSurfaceHandle)
{
	obs_enter_graphics();

	gs_texture_t *newTexture = gs_texture_create(width, height, GS_BGRA, 1,
		nullptr, GS_DYNAMIC);

	obs_leave_graphics();

	*popupSurfaceHandle = newTexture;
	popupSurface = newTexture;
	popupX = x;
	popupY = y;

	return true;
}
Exemple #8
0
static inline void init_textures(struct dc_capture *capture)
{
	if (capture->compatibility)
		capture->texture = gs_texture_create(
				capture->width, capture->height,
				GS_BGRA, 1, NULL, GS_DYNAMIC);
	else
		capture->texture = gs_texture_create_gdi(
				capture->width, capture->height);

	if (!capture->texture) {
		blog(LOG_WARNING, "[dc_capture_init] Failed to "
				  "create textures");
		return;
	}

	capture->valid = true;
}
bool BrowserSource::Impl::Listener::CreateSurface(int width, int height, 
		BrowserSurfaceHandle *surfaceHandle)
{
	//TODO: We can't lock graphics on CEF thread
	// as there may be a synchronous call
	obs_enter_graphics();

	gs_texture_t *newTexture =  gs_texture_create(width, height, GS_BGRA, 1, 
			nullptr, GS_DYNAMIC);
	
	obs_leave_graphics();

	textureSet.insert(newTexture);

	*surfaceHandle = newTexture;

	return true;
}
Exemple #10
0
gs_texture_t *gs_texture_create_from_file(const char *file)
{
	struct ffmpeg_image image;
	gs_texture_t           *tex = NULL;

	if (ffmpeg_image_init(&image, file)) {
		uint8_t *data = malloc(image.cx * image.cy * 4);
		if (ffmpeg_image_decode(&image, data, image.cx * 4)) {
			tex = gs_texture_create(image.cx, image.cy,
					convert_format(image.format),
					1, (const uint8_t**)&data, 0);
		}

		ffmpeg_image_free(&image);
		free(data);
	}
	return tex;
}
static inline void copy_texture(gs_duplicator_t *d, ID3D11Texture2D *tex)
{
	D3D11_TEXTURE2D_DESC desc;
	tex->GetDesc(&desc);

	if (!d->texture ||
	    d->texture->width != desc.Width ||
	    d->texture->height != desc.Height) {

		delete d->texture;
		d->texture = (gs_texture_2d*)gs_texture_create(
				desc.Width, desc.Height,
				ConvertDXGITextureFormat(desc.Format), 1,
				nullptr, 0);
	}

	if (!!d->texture)
		d->device->context->CopyResource(d->texture->texture,
				tex);
}
Exemple #12
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;
}
Exemple #13
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;
}
Exemple #14
0
static bool obs_init_gpu_conversion(struct obs_video_info *ovi)
{
	struct obs_core_video *video = &obs->video;

	calc_gpu_conversion_sizes(ovi);

	if (!video->conversion_height) {
		blog(LOG_INFO, "GPU conversion not available for format: %u",
				(unsigned int)ovi->output_format);
		video->gpu_conversion = false;
		return true;
	}

	for (size_t i = 0; i < NUM_TEXTURES; i++) {
		video->convert_textures[i] = gs_texture_create(
				ovi->output_width, video->conversion_height,
				GS_RGBA, 1, NULL, GS_RENDER_TARGET);

		if (!video->convert_textures[i])
			return false;
	}

	return true;
}
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);
}
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();
	}
}
Exemple #17
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();
	}
}