Added more efficient damage buffer method
This commit is contained in:
		
							parent
							
								
									754017a2db
								
							
						
					
					
						commit
						51fbd8acef
					
				| @ -46,9 +46,8 @@ func (backend *Backend) drawCells (forceRedraw bool) (areas []image.Rectangle) { | |||||||
| 	for y := 0; y < height; y ++ { | 	for y := 0; y < height; y ++ { | ||||||
| 	for x := 0; x < width;  x ++ { | 	for x := 0; x < width;  x ++ { | ||||||
| 		if !forceRedraw && backend.application.Clean(x, y) { continue } | 		if !forceRedraw && backend.application.Clean(x, y) { continue } | ||||||
| 		backend.application.MarkClean(x, y) |  | ||||||
| 
 | 
 | ||||||
| 		cell := backend.application.Cell(x, y) | 		cell := backend.application.GetForRendering(x, y) | ||||||
| 		content := cell.Rune() | 		content := cell.Rune() | ||||||
| 
 | 
 | ||||||
| 		if forceRedraw && content < 32 { continue } | 		if forceRedraw && content < 32 { continue } | ||||||
| @ -93,13 +92,24 @@ func (backend *Backend) drawRune ( | |||||||
| 	if character < 32 { return } | 	if character < 32 { return } | ||||||
| 	 | 	 | ||||||
| 	origin := backend.originOfCell(x, y + 1) | 	origin := backend.originOfCell(x, y + 1) | ||||||
| 	destinationRectangle, mask, maskPoint, _, _ := backend.font.face.Glyph ( | 	destinationRectangle, mask, maskPoint, _, ok := backend.font.face.Glyph ( | ||||||
| 		fixed.Point26_6 { | 		fixed.Point26_6 { | ||||||
| 			X: fixed.I(origin.X), | 			X: fixed.I(origin.X), | ||||||
| 			Y: fixed.I(origin.Y - backend.metrics.descent), | 			Y: fixed.I(origin.Y - backend.metrics.descent), | ||||||
| 		}, | 		}, | ||||||
| 		character) | 		character) | ||||||
| 
 | 
 | ||||||
|  | 	if !ok { | ||||||
|  | 		println("warning") | ||||||
|  | 		strokeRectangle ( | ||||||
|  | 			&image.Uniform { | ||||||
|  | 				C: backend.config.Color(stone.ColorForeground), | ||||||
|  | 			}, | ||||||
|  | 			backend.canvas, | ||||||
|  | 			backend.boundsOfCell(x, y)) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if backend.drawCellBounds {	 | 	if backend.drawCellBounds {	 | ||||||
| 		strokeRectangle ( | 		strokeRectangle ( | ||||||
| 			&image.Uniform { | 			&image.Uniform { | ||||||
|  | |||||||
							
								
								
									
										38
									
								
								buffer.go
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								buffer.go
									
									
									
									
									
								
							| @ -69,8 +69,8 @@ type Buffer interface { | |||||||
| // dirty by default, are only clean when marked as clean, and become dirty again | // dirty by default, are only clean when marked as clean, and become dirty again | ||||||
| // when they are altered in some way. | // when they are altered in some way. | ||||||
| type DamageBuffer struct { | type DamageBuffer struct { | ||||||
| 	content []Cell | 	content  []Cell | ||||||
| 	clean   []bool | 	onScreen []Cell | ||||||
| 	 | 	 | ||||||
| 	width  int | 	width  int | ||||||
| 	height int | 	height int | ||||||
| @ -127,9 +127,7 @@ func (buffer *DamageBuffer) SetColor (x, y int, color Color) { | |||||||
| 	defer buffer.lock.RUnlock() | 	defer buffer.lock.RUnlock() | ||||||
| 	 | 	 | ||||||
| 	if buffer.isOutOfBounds(x, y) { return } | 	if buffer.isOutOfBounds(x, y) { return } | ||||||
| 	index := x + y * buffer.width | 	buffer.content[x + y * buffer.width].color = color | ||||||
| 	buffer.clean[index] = buffer.content[index].color == color |  | ||||||
| 	buffer.content[index].color = color |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetSize sets the width and height of the buffer. This clears all data in the | // SetSize sets the width and height of the buffer. This clears all data in the | ||||||
| @ -139,10 +137,10 @@ func (buffer *DamageBuffer) SetSize (width, height int) { | |||||||
| 	defer buffer.lock.Unlock() | 	defer buffer.lock.Unlock() | ||||||
| 	 | 	 | ||||||
| 	if width < 0 || height < 0 { return } | 	if width < 0 || height < 0 { return } | ||||||
| 	buffer.width   = width | 	buffer.width    = width | ||||||
| 	buffer.height  = height | 	buffer.height   = height | ||||||
| 	buffer.content = make([]Cell, width * height) | 	buffer.content  = make([]Cell, width * height) | ||||||
| 	buffer.clean   = make([]bool, width * height) | 	buffer.onScreen = make([]Cell, width * height) | ||||||
| 	for index := 0; index < len(buffer.content); index ++ { | 	for index := 0; index < len(buffer.content); index ++ { | ||||||
| 		buffer.content[index].color = ColorForeground | 		buffer.content[index].color = ColorForeground | ||||||
| 	} | 	} | ||||||
| @ -154,9 +152,7 @@ func (buffer *DamageBuffer) SetStyle (x, y int, style Style) { | |||||||
| 	defer buffer.lock.RUnlock() | 	defer buffer.lock.RUnlock() | ||||||
| 	 | 	 | ||||||
| 	if buffer.isOutOfBounds(x, y) { return } | 	if buffer.isOutOfBounds(x, y) { return } | ||||||
| 	index := x + y * buffer.width | 	buffer.content[x + y * buffer.width].style = style | ||||||
| 	buffer.clean[index] = buffer.content[index].style == style |  | ||||||
| 	buffer.content[index].style = style |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetRune sets the rune of the cell at the specified x and y coordinates. | // SetRune sets the rune of the cell at the specified x and y coordinates. | ||||||
| @ -173,7 +169,6 @@ func (buffer *DamageBuffer) Clear () { | |||||||
| 	defer buffer.lock.RUnlock() | 	defer buffer.lock.RUnlock() | ||||||
| 
 | 
 | ||||||
| 	for index := 0; index < len(buffer.content); index ++ { | 	for index := 0; index < len(buffer.content); index ++ { | ||||||
| 		buffer.clean[index] = false |  | ||||||
| 		buffer.content[index] = Cell { | 		buffer.content[index] = Cell { | ||||||
| 			color: ColorForeground, | 			color: ColorForeground, | ||||||
| 		} | 		} | ||||||
| @ -182,9 +177,7 @@ func (buffer *DamageBuffer) Clear () { | |||||||
| 
 | 
 | ||||||
| func (buffer *DamageBuffer) setRune (x, y int, content rune) { | func (buffer *DamageBuffer) setRune (x, y int, content rune) { | ||||||
| 	if buffer.isOutOfBounds(x, y) { return } | 	if buffer.isOutOfBounds(x, y) { return } | ||||||
| 	index := x + y * buffer.width | 	buffer.content[x + y * buffer.width].content = content | ||||||
| 	buffer.clean[index] = buffer.content[index].content == content |  | ||||||
| 	buffer.content[index].content = content |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Write writes data stored in a byte slice to the buffer at the current dot | // Write writes data stored in a byte slice to the buffer at the current dot | ||||||
| @ -212,15 +205,20 @@ func (buffer *DamageBuffer) Clean (x, y int) (clean bool) { | |||||||
| 	defer buffer.lock.RUnlock() | 	defer buffer.lock.RUnlock() | ||||||
| 	 | 	 | ||||||
| 	if buffer.isOutOfBounds(x, y) { return } | 	if buffer.isOutOfBounds(x, y) { return } | ||||||
| 	clean = buffer.clean[x + y * buffer.width] | 	index := x + y * buffer.width | ||||||
|  | 	clean = buffer.content[index] == buffer.onScreen[index] | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // MarkClean marks the cell at the specified x and y coordinates as clean. | // GetForRendering returns the cell at the specified x and y coordinates and | ||||||
| func (buffer *DamageBuffer) MarkClean (x, y int) { | // marks it as clean. | ||||||
|  | func (buffer *DamageBuffer) GetForRendering (x, y int) (cell Cell) { | ||||||
| 	buffer.lock.RLock() | 	buffer.lock.RLock() | ||||||
| 	defer buffer.lock.RUnlock() | 	defer buffer.lock.RUnlock() | ||||||
| 	 | 	 | ||||||
| 	if buffer.isOutOfBounds(x, y) { return } | 	if buffer.isOutOfBounds(x, y) { return } | ||||||
| 	buffer.clean[x + y * buffer.width] = true | 	index := x + y * buffer.width | ||||||
|  | 	buffer.onScreen[index] = buffer.content[index] | ||||||
|  | 	cell = buffer.content[index] | ||||||
|  | 	return | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user