CGLayer resolution on iPhone with Retina display
-
In my UIView's drawRect: I derive a CGLayer from the current context, draw
into it, and then draw the layer into the context (the view). This still
works on iPhone with a Retina display, but the drawing is blocky. You can
see the problem perfectly with Apple's own example code (DrawFlag) in the
CGLayer Drawing page of the Quartz 2D Programming Guide - the stars in the
flag are blocky.
I can work around the problem for a double-resolution screen by creating a
CGLayer twice the size I need, applying a doubling scale transform, drawing
as before into the CGLayer, and then drawing the CGLayer into my view's
context scaled back down again.
But I feel I shouldn't have to do this. Given that the documentation claims
that "a CGLayer has all the characteristics of the graphics context [from
which it is derived] - its resolution, colorspace, and graphics state
settings," might we call this a bug?
m.
--
matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
pantes anthropoi tou eidenai oregontai phusei
Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
AppleScript: the Definitive Guide, 2nd edition
http://www.tidbits.com/matt/default.html#applescriptthings
Take Control of Exploring & Customizing Snow Leopard
http://tinyurl.com/kufyy8
RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
TidBITS, Mac news and reviews since 1990, http://www.tidbits.com -
I believe you need to set the scale of the layer to the scale of the device. Here is how we do it where appContentScaleFactor is a global variable we store the scale from at startup:
if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
appContentScaleFactor = [[UIScreen mainScreen] scale];
if ([mainLayer respondsToSelector: @selector(setContentsScale:)])
mainLayer.contentsScale = appContentScaleFactor;
On Aug 28, 2010, at 3:22 PM, Matt Neuburg wrote:
> In my UIView's drawRect: I derive a CGLayer from the current context, draw
> into it, and then draw the layer into the context (the view). This still
> works on iPhone with a Retina display, but the drawing is blocky. You can
> see the problem perfectly with Apple's own example code (DrawFlag) in the
> CGLayer Drawing page of the Quartz 2D Programming Guide - the stars in the
> flag are blocky.
>
> I can work around the problem for a double-resolution screen by creating a
> CGLayer twice the size I need, applying a doubling scale transform, drawing
> as before into the CGLayer, and then drawing the CGLayer into my view's
> context scaled back down again.
>
> But I feel I shouldn't have to do this. Given that the documentation claims
> that "a CGLayer has all the characteristics of the graphics context [from
> which it is derived] - its resolution, colorspace, and graphics state
> settings," might we call this a bug?
>
> m.
>
> --
> matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
> pantes anthropoi tou eidenai oregontai phusei
> Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
> AppleScript: the Definitive Guide, 2nd edition
> http://www.tidbits.com/matt/default.html#applescriptthings
> Take Control of Exploring & Customizing Snow Leopard
> http://tinyurl.com/kufyy8
> RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
> TidBITS, Mac news and reviews since 1990, http://www.tidbits.com
Alex Kac - President and Founder
Web Information Solutions, Inc.
"Forgiveness is not an occasional act: it is a permanent attitude."
-- Dr. Martin Luther King -
On Aug 28, 2010, at 1:37 PM, Alex Kac wrote:
> I believe you need to set the scale of the layer to the scale of the device. Here is how we do it where appContentScaleFactor is a global variable we store the scale from at startup:
>
> if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
> appContentScaleFactor = [[UIScreen mainScreen] scale];
>
>
> if ([mainLayer respondsToSelector: @selector(setContentsScale:)])
> mainLayer.contentsScale = appContentScaleFactor;
>
Sure, but a CGLayer has no contentsScale properties (or any other properties). A CGLayer isn't a CALayer... In fact I'm not sure they have anything in common. m.
>
> On Aug 28, 2010, at 3:22 PM, Matt Neuburg wrote:
>
>> In my UIView's drawRect: I derive a CGLayer from the current context, draw
>> into it, and then draw the layer into the context (the view). This still
>> works on iPhone with a Retina display, but the drawing is blocky. You can
>> see the problem perfectly with Apple's own example code (DrawFlag) in the
>> CGLayer Drawing page of the Quartz 2D Programming Guide - the stars in the
>> flag are blocky.
>>
>> I can work around the problem for a double-resolution screen by creating a
>> CGLayer twice the size I need, applying a doubling scale transform, drawing
>> as before into the CGLayer, and then drawing the CGLayer into my view's
>> context scaled back down again.
>>
>> But I feel I shouldn't have to do this. Given that the documentation claims
>> that "a CGLayer has all the characteristics of the graphics context [from
>> which it is derived] - its resolution, colorspace, and graphics state
>> settings," might we call this a bug?
>>
>> m.
>>
>> --
>> matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
>> pantes anthropoi tou eidenai oregontai phusei
>> Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
>> AppleScript: the Definitive Guide, 2nd edition
>> http://www.tidbits.com/matt/default.html#applescriptthings
>> Take Control of Exploring & Customizing Snow Leopard
>> http://tinyurl.com/kufyy8
>> RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
>> TidBITS, Mac news and reviews since 1990, http://www.tidbits.com
>
> Alex Kac - President and Founder
> Web Information Solutions, Inc.
>
> "Forgiveness is not an occasional act: it is a permanent attitude."
> -- Dr. Martin Luther King
>
>
>
>
-
On Aug 28, 2010, at 1:22 PM, Matt Neuburg wrote:
> In my UIView's drawRect: I derive a CGLayer from the current context, draw
> into it, and then draw the layer into the context (the view).
Out of curiosity is there any particular reason you are taking this approach?
--
David Duncan -
Ah, I just read the Layer part and didn’t think of a CGLayer. You are right - a CGLayer has nothing in common. That’s what I get for reading too quickly.
On Aug 28, 2010, at 9:18 PM, Matt Neuburg wrote:
>
> On Aug 28, 2010, at 1:37 PM, Alex Kac wrote:
>
>> I believe you need to set the scale of the layer to the scale of the device. Here is how we do it where appContentScaleFactor is a global variable we store the scale from at startup:
>>
>> if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
>> appContentScaleFactor = [[UIScreen mainScreen] scale];
>>
>>
>> if ([mainLayer respondsToSelector: @selector(setContentsScale:)])
>> mainLayer.contentsScale = appContentScaleFactor;
>>
>
> Sure, but a CGLayer has no contentsScale properties (or any other properties). A CGLayer isn't a CALayer... In fact I'm not sure they have anything in common. m.
>
>
>
>>
>> On Aug 28, 2010, at 3:22 PM, Matt Neuburg wrote:
>>
>>> In my UIView's drawRect: I derive a CGLayer from the current context, draw
>>> into it, and then draw the layer into the context (the view). This still
>>> works on iPhone with a Retina display, but the drawing is blocky. You can
>>> see the problem perfectly with Apple's own example code (DrawFlag) in the
>>> CGLayer Drawing page of the Quartz 2D Programming Guide - the stars in the
>>> flag are blocky.
>>>
>>> I can work around the problem for a double-resolution screen by creating a
>>> CGLayer twice the size I need, applying a doubling scale transform, drawing
>>> as before into the CGLayer, and then drawing the CGLayer into my view's
>>> context scaled back down again.
>>>
>>> But I feel I shouldn't have to do this. Given that the documentation claims
>>> that "a CGLayer has all the characteristics of the graphics context [from
>>> which it is derived] - its resolution, colorspace, and graphics state
>>> settings," might we call this a bug?
>>>
>>> m.
>>>
>>> --
>>> matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
>>> pantes anthropoi tou eidenai oregontai phusei
>>> Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
>>> AppleScript: the Definitive Guide, 2nd edition
>>> http://www.tidbits.com/matt/default.html#applescriptthings
>>> Take Control of Exploring & Customizing Snow Leopard
>>> http://tinyurl.com/kufyy8
>>> RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
>>> TidBITS, Mac news and reviews since 1990, http://www.tidbits.com
>>
>> Alex Kac - President and Founder
>> Web Information Solutions, Inc.
>>
>> "Forgiveness is not an occasional act: it is a permanent attitude."
>> -- Dr. Martin Luther King
>>
>>
>>
>>
>
Alex Kac - President and Founder
Web Information Solutions, Inc.
"I am not young enough to know everything."
--Oscar Wilde -
On or about 8/28/10 9:31 PM, thus spake "David Duncan"
<david.duncan...>:
> In the case of iOS for example, caching contents to CGLayers is rarely useful
> because it is rarely useful to use a software cache it is usually far more
> useful to use a hardware cache, which means CALayer or UIView, not CGLayer.
I bow to all you say; still the question remains whether, taken
dispassionately and in the abstract, it might be a useful behavior if
calling CGLayerCreateWithContext() would cause the resulting CGLayer to have
the "resolution" of the context from which it is created, as advertised, so
that drawing back into the same context with e.g. CGContextDrawLayerAtPoint
would not cause the ultimate drawing to have half the "resolution" on the
iPhone 4?
Just to repeat, the flag-drawing example on this page:
<http://developer.apple.com/iphone/library/documentation/GraphicsImaging/Con
ceptual/drawingwithquartz2d/dq_layers/dq_layers.html>
...is Apple's own, and behaves undesirably when the screen is
double-resolution, visibly drawing the flag's stars in single resolution. m.
--
matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
pantes anthropoi tou eidenai oregontai phusei
Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
AppleScript: the Definitive Guide, 2nd edition
http://www.tidbits.com/matt/default.html#applescriptthings
Take Control of Exploring & Customizing Snow Leopard
http://tinyurl.com/kufyy8
RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
TidBITS, Mac news and reviews since 1990, http://www.tidbits.com -
I would recommend you file a bug.
--
David Duncan
On Aug 29, 2010, at 9:38 AM, Matt Neuburg <matt...> wrote:
> On or about 8/28/10 9:31 PM, thus spake "David Duncan"> ceptual/drawingwithquartz2d/dq_layers/dq_layers.html>
> <david.duncan...>:
>
>> In the case of iOS for example, caching contents to CGLayers is rarely useful
>> because it is rarely useful to use a software cache – it is usually far more
>> useful to use a hardware cache, which means CALayer or UIView, not CGLayer.
>
> I bow to all you say; still the question remains whether, taken
> dispassionately and in the abstract, it might be a useful behavior if
> calling CGLayerCreateWithContext() would cause the resulting CGLayer to have
> the "resolution" of the context from which it is created, as advertised, so
> that drawing back into the same context with e.g. CGContextDrawLayerAtPoint
> would not cause the ultimate drawing to have half the "resolution" on the
> iPhone 4?
>
> Just to repeat, the flag-drawing example on this page:
>
> <http://developer.apple.com/iphone/library/documentation/GraphicsImaging/Con
>
> ...is Apple's own, and behaves undesirably when the screen is
> double-resolution, visibly drawing the flag's stars in single resolution. m.
>
> --
> matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
> pantes anthropoi tou eidenai oregontai phusei
> Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
> AppleScript: the Definitive Guide, 2nd edition
> http://www.tidbits.com/matt/default.html#applescriptthings
> Take Control of Exploring & Customizing Snow Leopard
> http://tinyurl.com/kufyy8
> RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
> TidBITS, Mac news and reviews since 1990, http://www.tidbits.com
>
>
>
-
On or about 8/28/10 9:31 PM, thus spake "David Duncan"
<david.duncan...>:
> it is usually far more
> useful to use a hardware cache, which means CALayer or UIView, not CGLayer.
Sorry to keep coming back to this, but the documentation implies that
CGLayer *is* a hardware cache - that's why I was using it. For example, the
documentation says:
> Before you call this or any routine that uses CGLayer objects, you must check
> to make sure that the system is running Mac OS X v10.4 or later and has a
> graphics card that supports using CGLayer objects
This suggests that CGLayer is implemented in hardware; otherwise surely the
check for a proper graphics card wouldn't be necessary? But perhaps I'm
misunderstanding.... m.
--
matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
pantes anthropoi tou eidenai oregontai phusei
Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
AppleScript: the Definitive Guide, 2nd edition
http://www.tidbits.com/matt/default.html#applescriptthings
Take Control of Exploring & Customizing Snow Leopard
http://tinyurl.com/kufyy8
RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
TidBITS, Mac news and reviews since 1990, http://www.tidbits.com -
On Aug 29, 2010, at 11:21 AM, Matt Neuburg wrote:
> On or about 8/28/10 9:31 PM, thus spake "David Duncan"
> <david.duncan...>:
>
>> it is usually far more
>> useful to use a hardware cache, which means CALayer or UIView, not CGLayer.
>
> Sorry to keep coming back to this, but the documentation implies that
> CGLayer *is* a hardware cache - that's why I was using it. For example, the
> documentation says:
It is (potentially) a hardware cache on the desktop in certain situations. Nothing in CG is hardware accelerated on iOS however, and CGLayer is no exception.
>> Before you call this or any routine that uses CGLayer objects, you must check
>> to make sure that the system is running Mac OS X v10.4 or later and has a
>> graphics card that supports using CGLayer objects
>
> This suggests that CGLayer is implemented in hardware; otherwise surely the
> check for a proper graphics card wouldn't be necessary? But perhaps I'm
> misunderstanding.... m.
If you require hardware acceleration of CGLayer objects perhaps, but to simply use CGLayers requires no such check. This would be a bug in the documentation.
Much of the shared documentation between iOS and Mac OS X will contain information that is incorrect for one platform or another. We strive to point out where information applies to only one platform or another, but this is an ongoing effort.
--
David Duncan -
On Sun, Aug 29, 2010 at 2:10 PM, David Duncan <david.duncan...>wrote:
> On Aug 29, 2010, at 11:21 AM, Matt Neuburg wrote:
>
>> On or about 8/28/10 9:31 PM, thus spake "David Duncan"
>> <david.duncan...>:
>>
>>> it is usually far more
>>> useful to use a hardware cache, which means CALayer or UIView, not
> CGLayer.
>>
>> Sorry to keep coming back to this, but the documentation implies that
>> CGLayer *is* a hardware cache - that's why I was using it. For example,
> the
>> documentation says:
>
> It is (potentially) a hardware cache on the desktop in certain situations.
> Nothing in CG is hardware accelerated on iOS however, and CGLayer is no
> exception.
>
Additionally, I don't think it's actually hardware accelerated on the
desktop either.
In practice at the moment, a CGLayer is basically a CGImage together with a
CGBitmapContext. I can think of case where something different happens, but
that case still doesn't use the GPU.
-Ken
Cocoa Frameworks
>
>>> Before you call this or any routine that uses CGLayer objects, you must
> check
>>> to make sure that the system is running Mac OS X v10.4 or later and has
> a
>>> graphics card that supports using CGLayer objects
>>
>> This suggests that CGLayer is implemented in hardware; otherwise surely
> the
>> check for a proper graphics card wouldn't be necessary? But perhaps I'm
>> misunderstanding.... m.
>
>
> If you require hardware acceleration of CGLayer objects perhaps, but to
> simply use CGLayers requires no such check. This would be a bug in the
> documentation.
>
> Much of the shared documentation between iOS and Mac OS X will contain
> information that is incorrect for one platform or another. We strive to
> point out where information applies to only one platform or another, but
> this is an ongoing effort.
> --
> David Duncan
>
-
On or about 8/29/10 2:54 PM, thus spake "Ken Ferry" <kenferry...>:
> In practice at the moment, a CGLayer is basically a CGImage together with a
> CGBitmapContext. I can think of case where something different happens, but
> that case still doesn't use the GPU.
Cool, once again I got the education I was after. Thx to all - m.
--
matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
pantes anthropoi tou eidenai oregontai phusei
Among the 2007 MacTech Top 25, http://tinyurl.com/2rh4pf
AppleScript: the Definitive Guide, 2nd edition
http://www.tidbits.com/matt/default.html#applescriptthings
Take Control of Exploring & Customizing Snow Leopard
http://tinyurl.com/kufyy8
RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
TidBITS, Mac news and reviews since 1990, http://www.tidbits.com


