我觉得我一定在这里遗漏了一些东西。我已将 NSOpenGLView 子类化,并尝试在 drawRect: 调用中绘制一个 CIImage。
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
let start = CFAbsoluteTimeGetCurrent()
openGLContext!.makeCurrentContext()
let cglContext = openGLContext!.CGLContextObj
let pixelFormat = openGLContext!.pixelFormat.CGLPixelFormatObj
let colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB)!
let options: [String: AnyObject] = [kCIContextOutputColorSpace: colorSpace]
let context = CIContext(CGLContext: cglContext, pixelFormat: pixelFormat, colorSpace: colorSpace, options: options)
context.drawImage(inputImage, inRect: self.bounds, fromRect: input.extent)
openGLContext!.flushBuffer()
let end = CFAbsoluteTimeGetCurrent()
Swift.print("updated view in \(end - start)")
}
我显然误以为 NSOpenGLContext(及其底层的 CGLContext)可以包装在 CIContext 中,而且渲染到其中将在 View 中生成图像。但是在上面的代码中完成工作时,我不知道实际像素在哪里结束(因为 View 最终是空白的)。
如果我只是抓取当前的 NSGraphicsContext 并渲染到其中,那么我会在 NSOpenGLView 中得到一个图像,但渲染似乎需要大约 10 倍的时间(即通过将 CIContext 声明更改为此):
// Works, but is slow
let context = NSGraphicsContext.currentContext()!.CIContext!
也试过这个,它既慢又实际上不显示图像,使它成为双重失败:
// Doesn't work. AND it's slow.
input.drawInRect(bounds, fromRect: input.extent, operation: .CompositeDestinationAtop, fraction: 1.0)
简单的解决方案就是渲染一个CGImage,然后将它弹出到屏幕上(通过CGImage -> NSImage,然后是一个NSImageView,或支持 CALayer)。但这对我的情况来说性能不够。在我的应用程序中,我希望渲染几十个缩略图大小的图像,每个图像都有自己不同的 CIFilters 链,并在其基础图像发生变化时实时刷新它们。虽然它们各自在几毫秒内渲染(使用我当前的 CGImage-bracketed 路径),但 View 更新仍然在每秒几帧的数量级。
我目前使用的路径看起来像 CGImageRef -> CIImage -> Bunch of CIFilters -> CGImage -> assign to CALayer for display。但在渲染链的两端使用 CGImages 似乎会降低性能。
分析后,似乎大部分时间都花在了复制内存上,我想这是预料之中的,但效率不高。支持 CGImage 需要传送到 GPU,然后过滤,然后作为 CGImage 返回到主内存,然后(大概)直接返回到 GPU由 CALayer 缩放和显示。理想情况下,根图像(在过滤之前)将仅位于 GPU 上,结果将直接呈现到视频内存中,但我不知道如何实现这一点。我当前的渲染路径在 GPU 上进行像素粉碎(这太棒了!),但被四处穿梭的内存所淹没以实际显示该死的东西。
那么谁能告诉我如何通过将事物端到端地保存在 GPU 上的途径来进行 Core Image 过滤? (或者至少只需要一次交换该数据?)如果我有一个 IOSurface 支持的 CIImage,我如何在不触及主内存的情况下将其直接绘制到 UI?有什么提示吗?
最佳答案
在为此苦苦思索了一天之后,NSOpenGLView 仍然没有成功...但是,我想我可以通过 CAOpenGLLayer<> 相反,这对我来说很好:
class GLLayer: CAOpenGLLayer {
var image: CIImage?
override func drawInCGLContext(ctx: CGLContextObj, pixelFormat pf: CGLPixelFormatObj, forLayerTime t: CFTimeInterval, displayTime ts: UnsafePointer<CVTimeStamp>) {
if image == nil {
let url = NSURL(fileURLWithPath: "/Users/doug/Desktop/test.jpg")
image = CIImage(contentsOfURL: url)!
}
let colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB)!
let options: [String: AnyObject] = [kCIContextOutputColorSpace: colorSpace]
let context = CIContext(CGLContext: ctx, pixelFormat: pf, colorSpace: colorSpace, options: options)
let targetRect = CGRectMake(-1, -1, 2, 2)
context.drawImage(image!, inRect: targetRect, fromRect: image!.extent)
}
}
请注意一件事 - CAOpenGLView 的坐标系不同。 View 为 2.0x2.0 单位,原点为 0,0(花了一些时间才弄明白)。除此之外,这与我最初问题中的非工作代码基本相同(除了,你知道,它实际上在这里工作)。也许 NSOpenGLView 类没有返回正确的上下文。谁知道。仍然对原因感兴趣,但至少我现在可以继续前进了。
关于objective-c - 将 CIImage 绘制到 NSOpenGLView(不访问主内存),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35078535/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U
我想从then子句中访问case语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案
我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内