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 x := 0; x < width;  x ++ { | ||||
| 		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() | ||||
| 
 | ||||
| 		if forceRedraw && content < 32 { continue } | ||||
| @ -93,13 +92,24 @@ func (backend *Backend) drawRune ( | ||||
| 	if character < 32 { return } | ||||
| 	 | ||||
| 	origin := backend.originOfCell(x, y + 1) | ||||
| 	destinationRectangle, mask, maskPoint, _, _ := backend.font.face.Glyph ( | ||||
| 	destinationRectangle, mask, maskPoint, _, ok := backend.font.face.Glyph ( | ||||
| 		fixed.Point26_6 { | ||||
| 			X: fixed.I(origin.X), | ||||
| 			Y: fixed.I(origin.Y - backend.metrics.descent), | ||||
| 		}, | ||||
| 		character) | ||||
| 
 | ||||
| 	if !ok { | ||||
| 		println("warning") | ||||
| 		strokeRectangle ( | ||||
| 			&image.Uniform { | ||||
| 				C: backend.config.Color(stone.ColorForeground), | ||||
| 			}, | ||||
| 			backend.canvas, | ||||
| 			backend.boundsOfCell(x, y)) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if backend.drawCellBounds {	 | ||||
| 		strokeRectangle ( | ||||
| 			&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 | ||||
| // when they are altered in some way. | ||||
| type DamageBuffer struct { | ||||
| 	content []Cell | ||||
| 	clean   []bool | ||||
| 	content  []Cell | ||||
| 	onScreen []Cell | ||||
| 	 | ||||
| 	width  int | ||||
| 	height int | ||||
| @ -127,9 +127,7 @@ func (buffer *DamageBuffer) SetColor (x, y int, color Color) { | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	index := x + y * buffer.width | ||||
| 	buffer.clean[index] = buffer.content[index].color == color | ||||
| 	buffer.content[index].color = color | ||||
| 	buffer.content[x + y * buffer.width].color = color | ||||
| } | ||||
| 
 | ||||
| // 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() | ||||
| 	 | ||||
| 	if width < 0 || height < 0 { return } | ||||
| 	buffer.width   = width | ||||
| 	buffer.height  = height | ||||
| 	buffer.content = make([]Cell, width * height) | ||||
| 	buffer.clean   = make([]bool, width * height) | ||||
| 	buffer.width    = width | ||||
| 	buffer.height   = height | ||||
| 	buffer.content  = make([]Cell, width * height) | ||||
| 	buffer.onScreen = make([]Cell, width * height) | ||||
| 	for index := 0; index < len(buffer.content); index ++ { | ||||
| 		buffer.content[index].color = ColorForeground | ||||
| 	} | ||||
| @ -154,9 +152,7 @@ func (buffer *DamageBuffer) SetStyle (x, y int, style Style) { | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	index := x + y * buffer.width | ||||
| 	buffer.clean[index] = buffer.content[index].style == style | ||||
| 	buffer.content[index].style = style | ||||
| 	buffer.content[x + y * buffer.width].style = style | ||||
| } | ||||
| 
 | ||||
| // 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() | ||||
| 
 | ||||
| 	for index := 0; index < len(buffer.content); index ++ { | ||||
| 		buffer.clean[index] = false | ||||
| 		buffer.content[index] = Cell { | ||||
| 			color: ColorForeground, | ||||
| 		} | ||||
| @ -182,9 +177,7 @@ func (buffer *DamageBuffer) Clear () { | ||||
| 
 | ||||
| func (buffer *DamageBuffer) setRune (x, y int, content rune) { | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	index := x + y * buffer.width | ||||
| 	buffer.clean[index] = buffer.content[index].content == content | ||||
| 	buffer.content[index].content = content | ||||
| 	buffer.content[x + y * buffer.width].content = content | ||||
| } | ||||
| 
 | ||||
| // 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() | ||||
| 	 | ||||
| 	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 | ||||
| } | ||||
| 
 | ||||
| // MarkClean marks the cell at the specified x and y coordinates as clean. | ||||
| func (buffer *DamageBuffer) MarkClean (x, y int) { | ||||
| // GetForRendering returns the cell at the specified x and y coordinates and | ||||
| // marks it as clean. | ||||
| func (buffer *DamageBuffer) GetForRendering (x, y int) (cell Cell) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	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