Esempio n. 1
0
static bool set_target(device_t device, texture_t tex, int side, zstencil_t zs)
{
	struct fbo_info *fbo;

	if (device->cur_render_target   == tex &&
	    device->cur_zstencil_buffer == zs  &&
	    device->cur_render_side     == side)
		return true;

	device->cur_render_target   = tex;
	device->cur_render_side     = side;
	device->cur_zstencil_buffer = zs;

	if (!tex)
		return set_current_fbo(device, NULL);

	fbo = get_fbo(device, tex);
	if (!fbo)
		return false;

	set_current_fbo(device, fbo);

	if (!attach_rendertarget(fbo, tex, side))
		return false;
	if (!attach_zstencil(fbo, zs))
		return false;

	return true;
}
Esempio n. 2
0
int GlslManager::render_frame_texture(mlt_service service, mlt_frame frame, int width, int height, uint8_t **image)
{
	EffectChain* chain = get_chain( service );
	if (!chain) return 1;
	glsl_fbo fbo = get_fbo( width, height );
	if (!fbo) return 1;
	glsl_texture texture = get_texture( width, height, GL_RGBA );
	if (!texture) {
		release_fbo( fbo );
		return 1;
	}

	glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
	check_error();
	glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
	check_error();
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	check_error();

	render_fbo( service, chain, fbo->fbo, width, height );

	glFinish();
	check_error();
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	check_error();
	release_fbo( fbo );

	*image = (uint8_t*) &texture->texture;
	mlt_frame_set_image( frame, *image, 0, NULL );
	mlt_properties_set_data( MLT_FRAME_PROPERTIES(frame), "movit.convert.texture", texture, 0,
		(mlt_destructor) GlslManager::release_texture, NULL );

	return 0;
}
Esempio n. 3
0
static inline struct fbo_info *get_fbo_by_tex(struct gs_device *device,
		gs_texture_t tex)
{
	uint32_t width, height;
	if (!get_tex_dimensions(tex, &width, &height))
		return NULL;

	return get_fbo(device, width, height, tex->format);
}
Esempio n. 4
0
/* Apparently for mac, PBOs won't do an asynchronous transfer unless you use
 * FBOs aong with glReadPixels, which is really dumb. */
void device_stage_texture(device_t device, stagesurf_t dst, texture_t src)
{
	struct gs_texture_2d *tex2d = (struct gs_texture_2d*)src;
	struct fbo_info *fbo;
	GLint last_fbo;
	bool success = false;

	if (!can_stage(dst, tex2d))
		goto failed;

	if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, dst->pack_buffer))
		goto failed;

	fbo = get_fbo(device, dst->width, dst->height, dst->format);

	if (!gl_get_integer_v(GL_READ_FRAMEBUFFER_BINDING, &last_fbo))
		goto failed_unbind_buffer;
	if (!gl_bind_framebuffer(GL_READ_FRAMEBUFFER, fbo->fbo))
		goto failed_unbind_buffer;

	glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0,
			src->gl_target, src->texture, 0);
	if (!gl_success("glFrameBufferTexture2D"))
		goto failed_unbind_all;

	glReadPixels(0, 0, dst->width, dst->height, dst->gl_format,
			dst->gl_type, 0);
	if (!gl_success("glReadPixels"))
		goto failed_unbind_all;

	success = true;

failed_unbind_all:
	gl_bind_framebuffer(GL_READ_FRAMEBUFFER, last_fbo);

failed_unbind_buffer:
	gl_bind_buffer(GL_PIXEL_PACK_BUFFER, 0);

failed:
	if (!success)
		blog(LOG_ERROR, "device_stage_texture (GL) failed");
}
Esempio n. 5
0
int GlslManager::render_frame_rgba(mlt_service service, mlt_frame frame, int width, int height, uint8_t **image)
{
	EffectChain* chain = get_chain( service );
	if (!chain) return 1;
	glsl_fbo fbo = get_fbo( width, height );
	if (!fbo) return 1;
	glsl_texture texture = get_texture( width, height, GL_RGBA );
	if (!texture) {
		release_fbo( fbo );
		return 1;
	}

	// Use a PBO to hold the data we read back with glReadPixels().
	// (Intel/DRI goes into a slow path if we don't read to PBO.)
	int img_size = width * height * 4;
	glsl_pbo pbo = get_pbo( img_size );
	if (!pbo) {
		release_fbo( fbo );
		release_texture(texture);
		return 1;
	}

	// Set the FBO
	check_error();
	glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
	check_error();
	glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
	check_error();
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	check_error();

	render_fbo( service, chain, fbo->fbo, width, height );

	// Read FBO into PBO
	glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
	check_error();
	glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, pbo->pbo );
	check_error();
	glBufferData( GL_PIXEL_PACK_BUFFER_ARB, img_size, NULL, GL_STREAM_READ );
	check_error();
	glReadPixels( 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0) );
	check_error();

	// Copy from PBO
	uint8_t* buf = (uint8_t*) glMapBuffer( GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY );
	check_error();
	*image = (uint8_t*) mlt_pool_alloc( img_size );
	mlt_frame_set_image( frame, *image, img_size, mlt_pool_release );
	memcpy( *image, buf, img_size );

	// Convert BGRA to RGBA
	register uint8_t *p = *image;
	register int n = width * height + 1;
	while ( --n ) {
		uint8_t b = p[0];
		*p = p[2]; p += 2;
		*p = b; p += 2;
	}

	// Release PBO and FBO
	glUnmapBuffer( GL_PIXEL_PACK_BUFFER_ARB );
	check_error();
	glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, 0 );
	check_error();
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	check_error();
	glBindTexture( GL_TEXTURE_2D, 0 );
	check_error();
	mlt_properties_set_data( MLT_FRAME_PROPERTIES(frame), "movit.convert.texture", texture, 0,
		(mlt_destructor) GlslManager::release_texture, NULL);
	release_fbo( fbo );

	return 0;
}
Esempio n. 6
0
void ContextPoolContext::setup_for_pass(const ShaderPass &pass, const RenderOuputGroup& output)
{
    // TODO Capture state object and bind if exists?
    const RenderTarget& target = output.get_render_target(pass.out);
    if (pass.in >= 0) {
        const RenderTarget& in_target = output.get_render_target(pass.in);
        for (size_t i = 1; i <= in_target.num_attachments; ++i) {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, in_target.attachments[i - 1]);
        }
    }

    gl->glBindFramebuffer(GL_FRAMEBUFFER, get_fbo(target));
    GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
                        GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3,
                        GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5};
    gl->glDrawBuffers(target.num_attachments, buffers);
    gl->glViewport(0, 0, target.width, target.height);

    if (pass.color_mask) {
        gl->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    } else {
        gl->glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    }

    if (pass.depth_mask) {
        gl->glDepthMask(GL_TRUE);
    } else {
        gl->glDepthMask(GL_FALSE);
    }

    if (pass.stencil_mask) {
        gl->glStencilMask(GL_TRUE);
    } else {
        gl->glStencilMask(GL_FALSE);
    }

    if (pass.depth_func == ShaderPass::DISABLED) {
        gl->glDisable(GL_DEPTH_TEST);
    } else {
        gl->glEnable(GL_DEPTH_TEST);
        gl->glDepthFunc(pass.depth_func);
    }

    if (pass.cull_face == ShaderPass::DISABLED) {
        gl->glDisable(GL_CULL_FACE);
    } else {
        gl->glEnable(GL_CULL_FACE);
        gl->glCullFace(pass.cull_face);
    }

    if (pass.blend_equation == ShaderPass::DISABLED) {
        gl->glDisable(GL_BLEND);
    } else {
        gl->glEnable(GL_BLEND);
        gl->glBlendEquation(pass.blend_equation);
        gl->glBlendFunc(pass.blend_src, pass.blend_dst);
    }

    if (pass.stencil_func == ShaderPass::DISABLED) {
        gl->glDisable(GL_STENCIL_TEST);
    } else {
        gl->glEnable(GL_STENCIL_TEST);
        gl->glStencilFunc(pass.stencil_func, 0, 0);
        //gl->glStencilOpSeparate(GL_BACK, , , );
        //gl->glStencilOpSeparate(GL_FRONT, , , );
    }

    if (pass.clear != ShaderPass::DISABLED) {
        gl->glClear(pass.clear);
    }
}