[Bf-blender-cvs] [e38f914] master: Cycles: use vertex buffers when possible to draw tiles on the screen.

Antony Riakiotakis noreply at git.blender.org
Mon May 11 16:28:56 CEST 2015


Commit: e38f9144212dc0e7e7f3e6be9b3315435d1669eb
Author: Antony Riakiotakis
Date:   Mon May 11 16:28:41 2015 +0200
Branches: master
https://developer.blender.org/rBe38f9144212dc0e7e7f3e6be9b3315435d1669eb

Cycles: use vertex buffers when possible to draw tiles on the screen.

Not terribly necessary in this case, since we are just drawing a quad,
but makes blender overall more GL 3.x core ready.

===================================================================

M	intern/cycles/device/device.cpp
M	intern/cycles/device/device.h
M	intern/cycles/device/device_cuda.cpp

===================================================================

diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 839f351..b34e064 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -33,6 +33,13 @@ CCL_NAMESPACE_BEGIN
 
 /* Device */
 
+Device::~Device()
+{
+	if(!background && vertex_buffer != 0) {
+		glDeleteBuffers(1, &vertex_buffer);
+	}
+}
+
 void Device::pixels_alloc(device_memory& mem)
 {
 	mem_alloc(mem, MEM_READ_WRITE);
@@ -67,6 +74,9 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
 		/* for multi devices, this assumes the inefficient method that we allocate
 		 * all pixels on the device even though we only render to a subset */
 		GLhalf *data_pointer = (GLhalf*)rgba.data_pointer;
+		float vbuffer[16], *basep;
+		float *vp = NULL;
+
 		data_pointer += 4*y*w;
 
 		/* draw half float texture, GLSL shader for display transform assumed to be bound */
@@ -83,18 +93,63 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
 			draw_params.bind_display_space_shader_cb();
 		}
 
-		glBegin(GL_QUADS);
-		
-		glTexCoord2f(0.0f, 0.0f);
-		glVertex2f(0.0f, dy);
-		glTexCoord2f(1.0f, 0.0f);
-		glVertex2f((float)width, dy);
-		glTexCoord2f(1.0f, 1.0f);
-		glVertex2f((float)width, (float)height + dy);
-		glTexCoord2f(0.0f, 1.0f);
-		glVertex2f(0.0f, (float)height + dy);
-
-		glEnd();
+		if(GLEW_VERSION_1_5) {
+			if (!vertex_buffer)
+				glGenBuffers(1, &vertex_buffer);
+
+			glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+			/* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
+			glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+			vp = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+			basep = NULL;
+		}
+		else {
+			basep = vbuffer;
+			vp = vbuffer;
+		}
+
+		if (vp) {
+			/* texture coordinate - vertex pair */
+			vp[0] = 0.0f;
+			vp[1] = 0.0f;
+			vp[2] = 0.0f;
+			vp[3] = dy;
+
+			vp[4] = 1.0f;
+			vp[5] = 0.0f;
+			vp[6] = (float)width;
+			vp[7] = dy;
+
+			vp[8] = 1.0f;
+			vp[9] = 1.0f;
+			vp[10] = (float)width;
+			vp[11] = (float)height + dy;
+
+			vp[12] = 0.0f;
+			vp[13] = 1.0f;
+			vp[14] = 0.0f;
+			vp[15] = (float)height + dy;
+
+			if (vertex_buffer)
+				glUnmapBuffer(GL_ARRAY_BUFFER);
+		}
+
+		glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), basep);
+		glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), ((char *)basep) + 2 * sizeof(float));
+
+		glEnableClientState(GL_VERTEX_ARRAY);
+		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+		glDisableClientState(GL_VERTEX_ARRAY);
+
+		if(vertex_buffer) {
+			glBindBuffer(GL_ARRAY_BUFFER, 0);
+		}
 
 		if(draw_params.unbind_display_space_shader_cb) {
 			draw_params.unbind_display_space_shader_cb();
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 162f512..b32f7b4 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -119,13 +119,16 @@ struct DeviceDrawParams {
 
 class Device {
 protected:
-	Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), info(info_), stats(stats_) {}
+	Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), vertex_buffer(0), info(info_), stats(stats_) {}
 
 	bool background;
 	string error_msg;
 
+	/* used for real time display */
+	unsigned int vertex_buffer;
+
 public:
-	virtual ~Device() {}
+	virtual ~Device();
 
 	/* info */
 	DeviceInfo info;
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 42d4f8e..be6a1f3 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -885,6 +885,7 @@ public:
 	{
 		if(!background) {
 			PixelMem pmem = pixel_mem_map[mem.device_pointer];
+			float *vpointer;
 
 			cuda_push_context();
 
@@ -918,18 +919,52 @@ public:
 				draw_params.bind_display_space_shader_cb();
 			}
 
-			glBegin(GL_QUADS);
-			
-			glTexCoord2f(0.0f, 0.0f);
-			glVertex2f(0.0f, dy);
-			glTexCoord2f((float)w/(float)pmem.w, 0.0f);
-			glVertex2f((float)width, dy);
-			glTexCoord2f((float)w/(float)pmem.w, (float)h/(float)pmem.h);
-			glVertex2f((float)width, (float)height + dy);
-			glTexCoord2f(0.0f, (float)h/(float)pmem.h);
-			glVertex2f(0.0f, (float)height + dy);
-
-			glEnd();
+			if (!vertex_buffer)
+				glGenBuffers(1, &vertex_buffer);
+
+			glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+			/* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
+			glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+			vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+			if (vpointer) {
+				/* texture coordinate - vertex pair */
+				vpointer[0] = 0.0f;
+				vpointer[1] = 0.0f;
+				vpointer[2] = 0.0f;
+				vpointer[3] = dy;
+
+				vpointer[4] = (float)w/(float)pmem.w;
+				vpointer[5] = 0.0f;
+				vpointer[6] = (float)width;
+				vpointer[7] = dy;
+
+				vpointer[8] = (float)w/(float)pmem.w;
+				vpointer[9] = (float)h/(float)pmem.h;
+				vpointer[10] = (float)width;
+				vpointer[11] = (float)height + dy;
+
+				vpointer[12] = 0.0f;
+				vpointer[13] = (float)h/(float)pmem.h;
+				vpointer[14] = 0.0f;
+				vpointer[15] = (float)height + dy;
+
+				glUnmapBuffer(GL_ARRAY_BUFFER);
+			}
+
+			glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
+			glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)NULL + 2 * sizeof(float));
+
+			glEnableClientState(GL_VERTEX_ARRAY);
+			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+			glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+			glDisableClientState(GL_VERTEX_ARRAY);
+
+			glBindBuffer(GL_ARRAY_BUFFER, 0);
 
 			if(draw_params.unbind_display_space_shader_cb) {
 				draw_params.unbind_display_space_shader_cb();




More information about the Bf-blender-cvs mailing list