def _update(self): """ Update texture on GPU """ if self.pending_data: log.debug("GPU: Updating texture") start, stop = self.pending_data offset, nbytes = start, stop-start itemsize = self.strides[1] offset /= itemsize nbytes /= itemsize nbytes += offset % self.width offset -= offset % self.width nbytes += (self.width - ((offset + nbytes) % self.width)) % self.width x = 0 y = offset // self.width width = self.width height = nbytes // self.width gl.glBindTexture(self._target, self.handle) gl.glTexSubImage2D(self.target, 0, x, y, width, height, self._cpu_format, self.gtype, self) gl.glBindTexture(self._target, self.handle) self._pending_data = None self._need_update = False
def _update(self): """ Update texture on GPU """ if self.pending_data: log.debug("GPU: Updating texture") start, stop = self.pending_data offset, nbytes = start, stop - start itemsize = self.strides[1] offset /= itemsize nbytes /= itemsize nbytes += offset % self.width offset -= offset % self.width nbytes += (self.width - ((offset + nbytes) % self.width)) % self.width x = 0 y = offset // self.width width = self.width height = nbytes // self.width gl.glBindTexture(self._target, self.handle) gl.glTexSubImage2D(self.target, 0, x, y, width, height, self._cpu_format, self.gtype, self) gl.glBindTexture(self._target, self.handle) self._pending_data = None self._need_update = False
def _transfer_frame_pbo(self): # generate PBO's if self._video_thread.has_video_loaded and (self._pbo_shape != self._video_thread.frame.shape): if self._pbos is not None: gl.glDeleteBuffers(PBO_COUNT, self._pbos) self._pbo_shape = self._video_thread.frame.shape self._pbos = gl.glGenBuffers(PBO_COUNT) h, w, b = self._pbo_shape num_bytes = h*w*b for pbo in self._pbos: gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, pbo) gl.glBufferData(gl.GL_PIXEL_UNPACK_BUFFER, num_bytes, None, gl.GL_STREAM_DRAW) gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0) # generate/update OpenGL texture if (self._frame is None or self._frame.shape != self._pbo_shape) and self._pbo_shape is not None: self._frame = np.zeros(self._pbo_shape, dtype=np.uint8).view(gloo.Texture2D) self._frame.activate() self._frame.deactivate() # do the transfer of pixel data from cpu to gpu using PBO's # inspired by this: https://gist.github.com/roxlu/4663550 if self._video_thread.has_video_loaded and self._video_thread.frame_changed: self._video_thread.frame_changed = False pbo = self._pbos[self._pbo_index] gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, pbo) t = self._frame._handle h, w, b = self._pbo_shape assert t != None and t != 0 gl.glBindTexture(gl.GL_TEXTURE_2D, t) gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, w, h, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, None) h, w, b = self._pbo_shape num_bytes = h*w*b self._pbo_index = (self._pbo_index + 1) % PBO_COUNT pbo = self._pbos[self._pbo_index] gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, pbo) # this might be an alternative, but not so fast as tested so far #gl.glBufferSubData(gl.GL_PIXEL_UNPACK_BUFFER, 0, num_bytes, ctypes.c_void_p(self._video_thread.frame.ctypes.data)) ptr = gl.glMapBuffer(gl.GL_PIXEL_UNPACK_BUFFER, gl.GL_WRITE_ONLY) if ptr != 0: #start = time.time() ctypes.memmove(ctypes.c_voidp(ptr), ctypes.c_void_p(self._video_thread.frame.ctypes.data), num_bytes) #end = time.time() #elapsed = end - start #print("Took %.2fms, %.2fMB/s" % (elapsed * 1000, (num_bytes / 1000000) / elapsed)) gl.glUnmapBuffer(gl.GL_PIXEL_UNPACK_BUFFER) gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0)
def _update(self): log.debug("GPU: Updating texture cube") if self.need_update: gl.glEnable(gl.GL_TEXTURE_CUBE_MAP) gl.glBindTexture(self.target, self.handle) targets = [ gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X, gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ] for i, target in enumerate(targets): face = self[i] pending = self.pending_data extents = face._extents if pending is None: continue if pending[1] < extents[0]: continue if pending[0] > extents[1]: continue start = max(extents[0], pending[0]) - extents[0] stop = min(extents[1], pending[1]) - extents[0] offset, nbytes = start, stop - start itemsize = face.strides[1] offset /= itemsize nbytes /= itemsize nbytes += offset % self.width offset -= offset % self.width nbytes += (self.width - ((offset + nbytes) % self.width)) % self.width x = 0 y = offset // self.width width = self.width height = nbytes // self.width gl.glTexSubImage2D(target, 0, x, y, width, height, self._cpu_format, self.gtype, face) self._pending_data = None self._need_update = False
def _update(self): log.debug("GPU: Updating texture cube") if self.need_update: gl.glEnable(gl.GL_TEXTURE_CUBE_MAP) gl.glBindTexture(self.target, self.handle) targets = [ gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X, gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ] for i,target in enumerate(targets): face = self[i] pending = self.pending_data extents = face._extents if pending is None: continue if pending[1] < extents[0]: continue if pending[0] > extents[1]: continue start = max(extents[0], pending[0]) - extents[0] stop = min(extents[1], pending[1]) - extents[0] offset,nbytes = start, stop-start itemsize = face.strides[1] offset /= itemsize nbytes /= itemsize nbytes += offset % self.width offset -= offset % self.width nbytes += (self.width - ((offset + nbytes) % self.width)) % self.width x = 0 y = offset // self.width width = self.width height = nbytes // self.width gl.glTexSubImage2D(target, 0, x, y, width, height, self._cpu_format, self.gtype, face) self._pending_data = None self._need_update = False