Index: /trunk/nv/gfx/cached_buffer.hh
===================================================================
--- /trunk/nv/gfx/cached_buffer.hh	(revision 117)
+++ /trunk/nv/gfx/cached_buffer.hh	(revision 118)
@@ -26,5 +26,5 @@
 
 		buffer_slice( cache* c ) 
-			: m_cache( c ), m_offset( 0 ), m_locked( true )
+			: m_cache( c ), m_offset( 0 ), m_cached_size( 0 ), m_locked( true )
 		{
 			m_cache->reset();
@@ -33,5 +33,6 @@
 		{
 			m_cache->commit( this );
-			m_locked = false;
+			m_cached_size = m_data.size();
+			m_locked      = false;
 		}
 		vector& lock()
@@ -54,4 +55,5 @@
 		cache* m_cache;
 		size_t m_offset;
+		size_t m_cached_size;
 		bool   m_locked;
 	};
@@ -90,7 +92,17 @@
 			{
 				const vector& bv = bslice->data();
-				std::copy( bv.cbegin(), bv.cend(), m_data.begin() + bslice->m_offset );
-				m_min = glm::min<int>( m_min, bslice->m_offset );
-				m_max = glm::max<int>( m_max, bslice->m_offset + bv.size() );
+				if ( bslice->m_cached_size != bv.size() ) 
+				{
+					m_data.erase( m_data.begin() + bslice->m_offset, m_data.end() );
+					m_full_update = true;
+					m_data.insert( m_data.end(), bv.cbegin(), bv.cend() );
+					m_min = glm::min<int>( m_min, bslice->m_offset );
+				}
+				else
+				{
+					std::copy( bv.cbegin(), bv.cend(), m_data.begin() + bslice->m_offset );
+					m_min = glm::min<int>( m_min, bslice->m_offset );
+					m_max = glm::max<int>( m_max, bslice->m_offset + bv.size() );
+				}
 			}
 		}
@@ -121,5 +133,14 @@
 			if ( m_full_update )
 			{
-				m_buffer->update( m_data.data(), 0, m_data.size() * value_type_size );
+				if ( m_min > 0 )
+				{
+					int offset = m_min * value_type_size;
+					int size   = m_data.size() * value_type_size - offset;
+					m_buffer->update( m_data.data() + m_min, offset, size );
+				}
+				else
+				{
+					m_buffer->update( m_data.data(), 0, m_data.size() * value_type_size );
+				}
 			}
 			else if ( m_max > 0 )
Index: /trunk/tests/cachebuf_test/nv_cachebuf_test.cc
===================================================================
--- /trunk/tests/cachebuf_test/nv_cachebuf_test.cc	(revision 117)
+++ /trunk/tests/cachebuf_test/nv_cachebuf_test.cc	(revision 118)
@@ -67,28 +67,64 @@
 {
 	app_window( nv::cached_buffer<quad>* cache, const glm::ivec2& a, const glm::ivec2& b, const glm::vec4& color )
-		: m_slice( cache )
-	{
-		glm::vec4 dcolor( color.x * 0.5, color.y * 0.5, color.z * 0.5, 1.0 );
-		std::vector<quad>& v = m_slice.lock();
-		nv::ivec2 a2( a.x, b.y );
-		nv::ivec2 b2( b.x, a.y );
-		nv::ivec2 t1( 10, 10 );
-		nv::ivec2 t2( -10, 10 );
-		v.emplace_back( a - t1, a,       b2, b2 - t2, dcolor );
-		v.emplace_back( a - t1, a2 + t2, a2, a,       dcolor );
-		v.emplace_back( a2 + t2, b + t1, b, a2, dcolor );
-		v.emplace_back( b + t1, b2 - t2, b2, b, dcolor );
-		v.emplace_back( a, b, color );
+		: m_slice( cache ), m_a( a ), m_b( b ), m_c( color )
+	{
+		create_complex();
 	}
 
 	void change_color( const glm::vec4& color )
 	{
+		m_c = color;
 		glm::vec4 dcolor( color.x * 0.5, color.y * 0.5, color.z * 0.5, 1.0 );
 		std::vector<quad>& v = m_slice.lock();
 		vertex* vtx = (vertex*)v.data();
-		for (size_t i = 0; i < (v.size() - 1) * 6; ++i )
-			vtx[i].color = color;
-		for (size_t i = (v.size() - 1) * 6; i < (v.size()) * 6; ++i )
-			vtx[i].color = dcolor;
+		if ( v.size() > 1 )
+		{
+			for (size_t i = 0; i < (v.size() - 1) * 6; ++i )
+				vtx[i].color = dcolor;
+			for (size_t i = (v.size() - 1) * 6; i < (v.size()) * 6; ++i )
+				vtx[i].color = color;
+		}
+		else
+		{
+			for (size_t i = 0; i < 6; ++i )
+				vtx[i].color = color;
+		}
+	}
+
+	void simplify_toggle()
+	{
+		if ( m_slice.data().size() > 1 )
+		{
+			NV_LOG( nv::LOG_INFO, "Simplifing" );
+			create_simple();
+		}
+		else
+		{
+			NV_LOG( nv::LOG_INFO, "Complexifing" );
+			create_complex();
+		}
+	}
+
+	void create_simple()
+	{
+		std::vector<quad>& v = m_slice.lock();
+		v.clear();
+		v.emplace_back( m_a, m_b, m_c );
+	}
+
+	void create_complex()
+	{
+		glm::vec4 dcolor( m_c.x * 0.5, m_c.y * 0.5, m_c.z * 0.5, 1.0 );
+		std::vector<quad>& v = m_slice.lock();
+		v.clear();
+		nv::ivec2 a2( m_a.x, m_b.y );
+		nv::ivec2 b2( m_b.x, m_a.y );
+		nv::ivec2 t1( 10, 10 );
+		nv::ivec2 t2( -10, 10 );
+		v.emplace_back( m_a - t1, m_a,       b2, b2 - t2, dcolor );
+		v.emplace_back( m_a - t1, a2 + t2, a2, m_a,       dcolor );
+		v.emplace_back( a2 + t2, m_b + t1, m_b, a2, dcolor );
+		v.emplace_back( m_b + t1, b2 - t2, b2, m_b, dcolor );
+		v.emplace_back( m_a, m_b, m_c );
 	}
 
@@ -99,4 +135,7 @@
 
 	nv::buffer_slice<quad> m_slice;
+	nv::ivec2 m_a;
+	nv::ivec2 m_b;
+	nv::vec4 m_c;
 };
 
@@ -109,4 +148,5 @@
 	void kill_window();
 	void spawn_window();
+	void simplify_window();
 	void recolor_window();
 	~application();
@@ -180,5 +220,5 @@
 		m_program->bind();
 //		m_program->set_uniform( "tex", 0 );
-		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, m_windows.size() * 5 * 6 );
+		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, m_quad_cache->get_size() * 6 );
 		m_window->swap_buffers();
 
@@ -197,4 +237,5 @@
 					{
 					case nv::KEY_N      : spawn_window(); break;
+					case nv::KEY_S      : simplify_window(); break;
 					case nv::KEY_C      : recolor_window(); break;
 					case nv::KEY_K      : kill_window(); break;
@@ -223,4 +264,5 @@
 	m_windows.erase( m_windows.begin() + index );
 }
+
 void application::recolor_window()
 {
@@ -228,4 +270,12 @@
 	size_t index = rand() % m_windows.size();
 	m_windows[ index ].change_color( nv::vec4( (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), 1.0 ) );
+}
+
+void application::simplify_window()
+{
+	if ( m_windows.size() == 0 ) return;
+	size_t index = rand() % m_windows.size();
+	NV_LOG( nv::LOG_INFO, "Simplify " << index );
+	m_windows[ index ].simplify_toggle();
 }
 
